Menggunakan grep dengan pipa dan ampersand untuk memfilter kesalahan dari find

22

Saya menggunakan cygwin untuk menemukan file di cygdrive.

Namun saya perlu menekan izin yang ditolak pesan (jika tidak hasilnya tersembunyi di pesan kesalahan). Perintah berikut ini berfungsi:

find -name 'myfile.*' |& grep -v "Permission denied"

Saya tidak mengerti mengapa ampersand perlu dimasukkan ke dalam perintah ini, akan berharap ini berfungsi tetapi tidak.

find -name 'myfile.*' | grep -v "Permission denied"

Tolong jelaskan arti dari ampersand.

Henrik K
sumber

Jawaban:

24

Dalam sistem mirip Unix, ada dua jalur keluaran yang jika dibiarkan tidak dimodifikasi akan mengirimkan keluaran ke layar Anda. Kesalahan standar (atau stderr) adalah kesalahan yang menangkap sebagian besar kegagalan dan kondisi kesalahan.

Untuk meneruskan pesan yang ditolak izinnya di stderr ke aliran output yang sama dengan "output reguler" Anda harus menggabungkan keduanya. Dalam contoh Anda, agar Anda grep -vdapat beroperasi dengan benar, Anda menggabungkan stdout (output standar) dan stderr dengan sintaksis misterius yang Anda lihat.

Dari bagian manual GNU Bash 3.2.2 Pipa :

Jika |&digunakan, kesalahan standar command1 , selain output standarnya, terhubung ke input standar command2 melalui pipa; itu adalah singkatan 2>&1 |. Pengalihan implisit kesalahan standar ke output standar dilakukan setelah setiap pengalihan ditentukan oleh perintah.

Juga, seperti yang ditunjukkan geirha, jika Anda hanya ingin menghilangkan output stderr, Anda ingin melakukan sesuatu seperti

find -name 'myfile.*' 2> /dev/null

atau mungkin

find -name 'myfile.*' 2> /tmp/errorlog

Dan perhatikan bahwa jika Anda memiliki string perintah, seperti findmeneruskan outputnya ke xargsAnda harus meletakkan seluruh pipa perintah dalam tanda kurung untuk menangkap output dari semua komponen perintah. Misalnya,

(find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 )  2> /dev/null

Jika Anda meninggalkan tanda kurung, dan lakukan ini sebagai gantinya -

find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 2> /dev/null

Anda masih akan melihat izin ditolak kesalahan dari find atau egrep, tetapi stderr akan diarahkan untuk xargs.

Seperti yang telah Anda lihat, Anda mungkin akan membuang stderr hanya setelah melihat isinya selama uji coba.

Perhatikan bahwa dengan GNU finddan sejauh yang saya tahu, apa pun yang sesuai dengan POSIX find, -printopsinya tersirat. Anda masih dapat menyediakannya secara eksplisit jika Anda mau.

belacqua
sumber
Tampaknya hanya bash4 + wiki.bash-hackers.org/bash4#redirection
Luke Exton
1
@LukeExton Ya. Dalam shell lain, 2>&1 |dapat digunakan sebagai pengganti |&(yaitu, seseorang dapat secara eksplisit mengarahkan stderr ke stdout dan kemudian menyalurkannya ke perintah berikutnya dalam pipa).
Eliah Kagan
2> >( grep filter )juga berguna
user1133275
1

Jika Anda ingin mengabaikan pesan kesalahan, cukup arahkan ulang stderr ke / dev / null.

find . -name 'myfile.*' -print 2>/dev/null

Juga, pertimbangkan untuk membaca http://mywiki.wooledge.org/UsingFind .

geirha
sumber