GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara menulis stderr ke file saat menggunakan tee dengan pipa?

Saya berasumsi Anda masih ingin melihat STDERR dan STDOUT di terminal. Anda bisa memilih jawaban Josh Kelley, tetapi saya menemukan menyimpan tail sekitar di latar belakang yang menghasilkan file log Anda sangat retas dan kaku. Perhatikan bagaimana Anda perlu menyimpan exra FD dan melakukan pembersihan sesudahnya dengan mematikannya dan secara teknis harus melakukannya di trap '...' EXIT .

Ada cara yang lebih baik untuk melakukannya, dan Anda telah menemukannya:tee .

Hanya saja, alih-alih hanya menggunakannya untuk stdout Anda, miliki tee untuk stdout dan satu untuk stderr. Bagaimana Anda akan mencapai ini? Substitusi proses dan pengalihan file:

command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

Mari kita bagi dan jelaskan:

> >(..)

>(...) (substitusi proses) membuat FIFO dan memungkinkan tee mendengarkannya. Kemudian, ia menggunakan > (pengalihan file) untuk mengalihkan STDOUT dari command ke FIFO bahwa tee pertama Anda sedang mendengarkan.

Hal yang sama untuk yang kedua:

2> >(tee -a stderr.log >&2)

Kami menggunakan substitusi proses lagi untuk membuat tee proses yang membaca dari STDIN dan membuangnya ke stderr.log . tee mengeluarkan inputnya kembali pada STDOUT, tetapi karena inputnya adalah STDERR kami, kami ingin mengarahkan ulang tee STDOUT ke STDERR kami lagi. Kemudian kami menggunakan pengalihan file untuk mengarahkan ulang command STDERR ke input FIFO (tee STDIN).

Lihat http://mywiki.wooledge.org/BashGuide/InputAndOutput

Pergantian proses adalah salah satu hal yang sangat menyenangkan yang Anda dapatkan sebagai bonus memilih bash sebagai shell Anda sebagai lawan dari sh (POSIX atau Bourne).

Di sh , Anda harus melakukannya secara manual:

out="${TMPDIR:-/tmp}/out.$$" err="${TMPDIR:-/tmp}/err.$$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"

mengapa tidak cukup:

./aaa.sh 2>&1 | tee -a log

Ini hanya mengalihkan stderr ke stdout , jadi tee menggemakan log dan screen. Mungkin saya melewatkan sesuatu, karena beberapa solusi lain tampaknya sangat rumit.

Catatan: Sejak bash versi 4 Anda dapat menggunakan |& sebagai singkatan dari 2>&1 | :

./aaa.sh |& tee -a log

Ini mungkin berguna bagi orang yang menemukan ini melalui google. Cukup batalkan komentar pada contoh yang ingin Anda coba. Tentu saja, jangan ragu untuk mengganti nama file keluaran.

#!/bin/bash

STATUSFILE=x.out
LOGFILE=x.log

### All output to screen
### Do nothing, this is the default


### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1


### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1


### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)


### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)


### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}


### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)


### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}


### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)


echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}

Linux
  1. Bagaimana Cara Menulis File Ke Yang Lain?

  2. Bagaimana Cara Mengarahkan Hanya Stderr?

  3. Bagaimana cara menulis file dengan C di Linux?

  1. Bagaimana cara menyalurkan panggilan subproses ke file teks?

  2. Bagaimana cara menulis integer ke file biner menggunakan Bash?

  3. Bagaimana Cara Menambahkan File di C, menggunakan Open in O_APPEND Mode di linux?

  1. Bagaimana cara menambahkan file sebagai sudo?

  2. Bagaimana cara mengubah file di tempat menggunakan awk? (seperti halnya sed -i)

  3. Menangkap STDERR dan STDOUT ke file menggunakan tee