GNU/Linux >> Belajar Linux >  >> Linux

Pipa hanya STDERR melalui filter

TL;DR:

$ cmd 2> >(stderr-filter >&2)

Contoh:

% cat /non-existant 2> >(tr o X >&2)
cat: /nXn-existant: NX such file Xr directXry
%

Ini akan bekerja di bash dan zsh. Bash cukup banyak di mana-mana akhir-akhir ini, namun, jika Anda benar-benar membutuhkan solusi (sangat degil) untuk POSIX sh , lalu lihat di sini.

Penjelasan

Sejauh ini, cara termudah untuk melakukannya adalah dengan mengalihkan STDERR melalui substitusi proses:

Substitusi proses memungkinkan input atau output proses dirujuk menggunakan nama file. Ini mengambil bentuk

>(list)

Daftar proses dijalankan secara asinkron, dan input atau outputnya muncul sebagai nama file.

Jadi yang Anda dapatkan dengan penggantian proses adalah nama file.

Seperti yang bisa Anda lakukan:

$ cmd 2> filename

kamu bisa melakukannya

$ cmd 2> >(filter >&2)

>&2 pengalihan filter STDOUT kembali ke STDERR asli.


TL;DR:(bash dan zsh)

$ cmd 2> >(stderr-filter >&2)

Contoh:

% cat /non-existant 2> >(tr o X >&2)
cat: /nXn-existant: NX such file Xr directXry
%

Banyak jawaban di jaringan StackExchange berbentuk:

cat /non-existant 3>&1 1>&2 2>&3 3>&- | sed 's/e/E/g'

Ini memiliki asumsi bawaan:deskriptor file 3 tidak digunakan untuk hal lain.

Sebagai gantinya, gunakan deskriptor file bernama, dan {ba,z}sh akan mengalokasikan deskriptor file berikutnya yang tersedia>=10:

cat /non-existant {tmp}>&1 1>&2 2>&$tmp {tmp}>&- | sed 's/e/E/g'

Perhatikan bahwa deskriptor file bernama tidak didukung oleh POSIX sh .

Masalah lain dengan hal di atas adalah bahwa perintah tidak dapat disalurkan ke perintah lebih lanjut tanpa lagi menukar STDOUT dan STDERR kembali ke nilai aslinya.

Untuk mengizinkan pemipaan selanjutnya di POSIX sh , (dan masih dengan asumsi FD 3 tidak digunakan) menjadi rumit:

(cmd 2>&1 >&3 3>&- | stderr-filter >&2 3>&-) 3>&1

Jadi, Mengingat asumsi dan sintaks degil ini, Anda mungkin lebih baik menggunakan bash yang lebih sederhana /zsh sintaks ditampilkan di TL;DR di atas, dan dijelaskan di sini.

demonstrasi praktis, hanya mengambil stderr:

$ ls -l . noexistABC noexistXYZ
ls: cannot access 'noexistABC': No such file or directory
ls: cannot access 'noexistXYZ': No such file or directory
.:
total 4
-rw-rw-r-- 1 frank frank    0 Aug 19 12:26 bar.txt
-rw-rw-r-- 1 frank frank    0 Aug 19 12:26 foo.txt
drwxrwxr-x 2 frank frank 4096 Aug 19 12:26 someFolder


$ ( ls -l . noexistABC noexistXYZ 2>&1 >&3 3>&- | grep ABC >&2 3>&-) 3>&1
.:
ls: cannot access 'noexistABC': No such file or directory
total 4
-rw-rw-r-- 1 frank frank    0 Aug 19 12:26 bar.txt
-rw-rw-r-- 1 frank frank    0 Aug 19 12:26 foo.txt
drwxrwxr-x 2 frank frank 4096 Aug 19 12:26 someFolder

Berikut ini sebuah contoh, yang dimodelkan setelah cara menukar deskriptor file di bash . Output dari a.out adalah sebagai berikut, tanpa awalan 'STDXXX:'.

STDERR: stderr output
STDOUT: more regular

./a.out 3>&1 1>&2 2>&3 3>&- | sed 's/e/E/g'
more regular
stdErr output

Mengutip dari tautan di atas:

  1. Pertama simpan stdout sebagai &3 (&1 ditipu menjadi 3)
  2. Selanjutnya kirim stdout ke stderr (&2 ditipu menjadi 1)
  3. Kirim stderr ke &3 (stdout) (&3 ditipu menjadi 2)
  4. tutup &3 (&- ditipu menjadi 3)

Penggunaan substitusi proses yang naif tampaknya memungkinkan pemfilteran stderr terpisah dari stdout :

:; ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 )
out
e:err

Perhatikan bahwa stderr keluar pada stderr dan stdout pada stdout , yang dapat kita lihat dengan membungkus semuanya dalam subkulit lain dan mengalihkan ke file o dan e

( ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 ) ) 1>o 2>e

Linux
  1. 6 opsi filter lalu lintas jaringan tcpdump

  2. Filter Rsync:Menyalin Satu Pola Saja?

  3. Ny Cara Menggunakan Xargs Di Pipa?

  1. Redirect Dan Output Pipa?

  2. Bagaimana Mengirim Perintah ke Terminal Apa Pun?

  3. Batalkan Penyelesaian, Tapi Hanya Penyelesaian, Di Zsh?

  1. Bagaimana Cara Memfilter Log Dmesg Untuk Melihat Hanya Kesalahan?

  2. Tampilkan Hanya Stderr Di Layar Tetapi Tulis Stdout Dan Stderr Ke File?

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