Использование grep с pipe и ampersand для фильтрации ошибок от find

Я использую Cygwin, чтобы найти файл на Cygdrive.

Однако мне нужно подавить сообщения об отказе в разрешении (в противном случае результаты будут скрыты в сообщениях об ошибках). Следующая команда работает:

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

Я не понимаю, почему амперсанд должен быть введен в эту команду, ожидал бы, что это сработает, но это не так.

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

Пожалуйста, объясните значение амперсанда.

22
задан 4 March 2019 в 21:07

3 ответа

Сообщения об ошибках записываются в stderr , а не в stdout , но | только для каналов stdout .

Вы, вероятно, хотите |&, , который передает stderr , а также stdout .

0
ответ дан 4 March 2019 в 21:07

В Unix-подобных системах есть два пути вывода, которые, если оставить их без изменений, отправят вывод на ваш экран. Стандартная ошибка (или stderr) - это та, которая фиксирует большинство сбоев и состояний ошибок.

Чтобы передать сообщение об отказе в разрешении в stderr тому же потоку вывода, что и «обычный вывод», необходимо объединить их. В вашем примере, чтобы ваш grep -v правильно работал с ним, вы комбинируете stdout (стандартный вывод) и stderr с тайным синтаксисом, который вы видите.

Из руководства по GNU Bash раздел 3.2.2 Конвейеры :

Если используется |&, command1 Стандартная ошибка, помимо стандартного выхода, связана со стандартным входом команды command2 через канал; это сокращение от 2>&1 |. Это неявное перенаправление стандартной ошибки на стандартный вывод выполняется после любых перенаправлений, указанных командой.

Кроме того, как указывает гейра, если вы хотите просто избавиться от вывода stderr, вам нужно сделать что-то вроде

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

или, возможно,

find -name 'myfile.*' 2> /tmp/errorlog
[ 1122] И обратите внимание, что если у вас есть строки команд, такие как 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

, вы все равно увидите ошибки, в которых отказано в разрешении из find или egrep, но stderr будет перенаправлено на xargs.

Как вы видели, вы, вероятно, выбросили бы stderr только после просмотра его содержимого во время тестового прогона.

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

0
ответ дан 4 March 2019 в 21:07

Если вы хотите игнорировать сообщения об ошибках, просто перенаправьте stderr в /dev/null.

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

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

0
ответ дан 4 March 2019 в 21:07

Другие вопросы по тегам:

Похожие вопросы: