Команда поиска трубы "stderr" к команде - PullRequest
3 голосов
/ 01 марта 2012

Привет, у меня есть особая проблема, и я очень стараюсь найти (каламбур) - решение для нее.

$> find ./subdirectory -type f 2>>error.log

Я получаю сообщение об ошибке, что-то вроде «find: ./subdirectory/noidea: В доступе отказано», и оно будет перенаправлено на error.log .

Можно ли как-нибудь передать stderr другой команде перед перенаправлением на error.log ?

Я хочу иметь возможность сделать что-то вроде

$> find ./subdirectory -type f 2 | sed "s#\(.*\)#${PWD}\1#" >> error.log

где я хочу передать только stderr команде sed и получить полный путь к ошибке команды find .

Я знаю, что здесь не работают трубопроводы и, вероятно, это неправильный путь.

Моя проблема в том, что мне нужны оба stdout и stderr , и оба должны обрабатываться разными способами одновременно.

EDIT: Хорошо. Небольшое изменение моей проблемы.

Теперь у меня есть сценарий оболочки, solve_problem.sh

В этом сценарии оболочки у меня есть следующий код

ErrorFile="error.log"
for directories in `find ./subdirectory -type f 2>> $ErrorFile`
do
    field1=`echo $directories | cut -d / -f2`
    field2=`echo $directories | cut -d / -f3`
done

Та же проблема, но внутри сценария оболочки. Ошибка «find: ./subdirectory/noidea: Permission denied» должна быть записана в $ ErrorFile , а stdout должен быть присвоен переменной $ directoryies .

Ответы [ 3 ]

2 голосов
/ 01 марта 2012

Pipe stderr и stdout одновременно - идея взята из этого поста :

(find /boot | sed s'/^/STDOUT:/' ) 3>&1 1>&2 2>&3 | sed 's/^/STDERR:/'

Пример вывода:

STDOUT:/boot/grub/usb_keyboard.mod
STDERR:find: `/boot/lost+found': Brak dostępu

Перенаправления Bash типа 3>&1 1>&2 2>&3 swaps stderrи stdout.

Я бы изменил ваш пример сценария так:

#!/bin/bash
ErrorFile="error.log"
(find ./subdirectory -type f 3>&1 1>&2 2>&3 | sed "s#^#${PWD}: #" >> $ErrorFile) 3>&1 1>&2 2>&3 | while read line; do
    field1=$(echo "$line" | cut -d / -f2)
    ...
done

Обратите внимание, что я дважды поменял stdout & stderr.

Небольшой дополнительный комментарий - посмотрите наОпция -printf на странице справки по поиску.Это может быть полезно для вас.

1 голос
/ 01 марта 2012

Если вам нужно перенаправить stderr на stdout, чтобы следующая команда в конвейере получила его в качестве ввода, то вы можете использовать 2>&1.

Для получения дополнительной информации, пожалуйста, ознакомьтесь с Все о перенаправлении Как.

Редактировать: Даже если вам нужно отредактировать проход stdout дальше в канале, вы можете использовать sed для фильтрации сообщений об ошибках и записи их в файл:

$ find . -type f 2>&1 | sed '/^find:/{
> w error.log
> d
> }'

В этом примере:

  • в find команда stderr перенаправлена ​​на stdout
  • в sed ошибки команды из find, которые соответствуют регулярному выражению, записываются в файл (w error.log) и удаляются из вывода (d).
  • любая команда в конвейере, следующем за конвейером, получит вывод от find.

Примечание: Это будет работать как lon, так как все сообщения об ошибках от find начинаются с find:. В противном случае регулярное выражение в sed должно быть изменено, чтобы соответствовать всем случаям.

0 голосов
/ 01 марта 2012

Вы можете попробовать это (на bash), которое, кажется, работает:

find ./subdirectory -type f 2> >(sed "s#\(.*\)#${PWD}\1#" >> error.log)

Это делает следующее:

  1. 2> перенаправляет stderr на
  2. >(...) подстановка процесса (выполняется sed, который добавляется в error.log)
...