Використовуючи grep з трубою та ampersand для фільтрації помилок з пошуку


22

Я використовую cygwin, щоб знайти файл на cygdrive.

Однак мені потрібно придушити повідомлення, відхилені в дозволі (інакше результати приховуються в повідомленнях про помилки). Наступна команда працює:

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

Я не розумію, чому амперсанд потрібно вводити в цю команду, очікував би, що це спрацює, але це не так.

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

Поясніть, будь ласка, значення амперсанда.

Відповіді:


24

У системах, схожих на Unix, є два вихідні контури, які, якщо їх не змінити, надішлють висновок на ваш екран. Стандартна помилка (або stderr) - це та, яка фіксує більшість відмов і умов помилок.

Щоб передати повідомлення відхиленого дозволу в stderr тому ж вихідному потоку, що і "регулярний вихід", ви повинні об'єднати два. У вашому прикладі, для того, щоб ваше grep -vправильно працювало над ним, ви поєднуєте stdout (стандартний вихід) та stderr із синтаксисом таємниці, який ви бачите.

З посібника GNU Bash, розділ 3.2.2 Трубопроводи :

Якщо |&використовується '', стандартна помилка command1 , крім стандартного виводу, підключається до стандартного вводу command2 через трубу; це скорочення для 2>&1 |. Це неявне перенаправлення стандартної помилки на стандартний висновок виконується після будь-яких перенаправлень, визначених командою.

Крім того, як вказує Гейрха, якщо ви хочете просто позбутися більш жорсткого виходу, ви хочете зробити щось на зразок

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

чи, можливо,

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

І зауважте, що якщо у вас є рядки команд, такі як findпередача її виводу, xargsвам потрібно буде поставити весь конвеєр команд у дужки, щоб захопити вихід з усіх компонентів команди. Наприклад,

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

Якщо ви залишили дужки, і зробили це замість цього -

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

ви все ще побачите дозвіл, якому відмовлено у помилках пошуку або egrep, але stderr буде переспрямовано на xargs.

Як ви вже бачили, ви, швидше за все, викинете stderr лише після перегляду його вмісту під час пробного запуску.

Зауважте, що з GNU findі наскільки я можу сказати, будь-яка сумісна з POSIX find, -printопція неявна. Ви все одно можете поставити його явно, якщо хочете.


Здається, лише bash4 + wiki.bash-hackers.org/bash4#redirection
Люк Екстон

1
@LukeExton Так. В інших оболонках 2>&1 |можуть використовуватися замість |&(тобто, явно можна перенаправити stderr на stdout, а потім передати його наступній команді в конвеєрі).
Елія Каган

2> >( grep filter )також зручно
користувач1133275


1

Якщо ви хочете ігнорувати повідомлення про помилки, просто перенаправляйте stderr на / dev / null.

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

Також розглянемо читання http://mywiki.wooledge.org/UsingFind .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.