Можно создать псевдоним для sudo + название сценария. Конечно, это - еще больше работы для установки, так как затем необходимо установить псевдоним также, но она сохраняет Вас от необходимости ввести sudo.
Но если Вы не возражаете против ужасных угроз безопасности, используйте оболочку setuid в качестве интерпретатора для сценария оболочки. Не знайте, будет ли это работать на Вас, но я предполагаю, что это могло бы.
Позвольте мне заявить, что я советую против фактического выполнения этого, все же. Я просто упоминаю это в образовательных целях ;-)
Если Вы используете bash
почему бы не использовать неименованные каналы, в сущности сокращение от какой сказанный phunehehe:
ffmpeg -i 01-Daemon.mp3 2> >(grep -i Duration)
Ни одна из обычных оболочек (даже zsh) не разрешает каналы кроме от stdout до stdin. Но весь стиль Границы окружает переназначение дескриптора файла поддержки (как в 1>&2
). Таким образом, можно временно отклонить stdout к fd 3 и stderr к stdout, и позже отложить fd 3 на stdout. Если stuff
производит некоторый вывод на stdout и некоторый вывод на stderr, и Вы хотите подать заявку filter
на выводе ошибок, оставляя стандартный вывод нетронутым, можно использовать { stuff 2>&1 1>&3 | filter 1>&2; } 3>&1
.
$ stuff () {
echo standard output
echo more output
echo standard error 1>&2
echo more error 1>&2
}
$ filter () {
grep a
}
$ { stuff 2>&1 1>&3 | filter 1>&2; } 3>&1
standard output
more output
standard error
pipestatus
помог бы
– Gilles 'SO- stop being evil'
27.04.2016, 02:15
set -o pipefail
может быть полезным здесь, в зависимости от того, что Вы хотите сделать с ошибочным состоянием. (Например, если Вы имеете set -e
включенный для сбоя на любых ошибках Вы, вероятно, хотите set -o pipefail
также.)
– Wildcard
27.04.2016, 02:21
Это подобно "временному приему файла phunehehe", но использует именованный канал вместо этого, позволяя Вам получить результаты немного ближе к тому, когда они производятся, который может быть удобным для продолжительных команд:
$ mkfifo mypipe
$ command 2> mypipe | grep "pattern" mypipe
В этой конструкции stderr будет направлен к каналу, названному "mypipe". С тех пор grep
был назван с аргументом файла, он не будет смотреть на STDIN для своего входа. К сожалению, необходимо будет все еще очистить тот именованный канал, после того как Вы сделаны.
При использовании Bash 4 существует синтаксис ярлыка для command1 2>&1 | command2
, который является command1 |& command2
. Однако я полагаю, что это - просто ярлык синтаксиса, Вы все еще перенаправляете STDERR к STDOUT.
|&
синтаксис прекрасен для чистки чрезмерно увеличенного в размере Ruby stderr отслеживания стека. Я могу наконец grep те, которые не имеют слишком большого количества стычки.
– pgr
02.04.2018, 14:28
Gilles и ответы Stefan Lasiewski оба хороши, но этот путь более прост:
ffmpeg -i 01-Daemon.mp3 2>&1 >/dev/null | grep "pattern"
Я предполагаю, что Вы не хотите ffmpeg's
stdout распечатан.
Как это работает:
Посмотрите ниже для сценария, используемого в этих тестах.
Grep может только воздействовать на stdin, поэтому необходимо преобразовать stderr поток в форме, которую может проанализировать Grep.
Обычно, stdout и stderr оба печатаются на Ваш экран:
$ ./stdout-stderr.sh
./stdout-stderr.sh: Printing to stdout
./stdout-stderr.sh: Printing to stderr
Чтобы скрыть stdout, но все еще распечатать stderr делают это:
$ ./stdout-stderr.sh >/dev/null
./stdout-stderr.sh: Printing to stderr
Но grep не будет воздействовать на stderr! Вы ожидали бы, что следующая команда подавит строки, которые содержат, 'допускают ошибку', но она не делает.
$ ./stdout-stderr.sh >/dev/null |grep --invert-match err
./stdout-stderr.sh: Printing to stderr
Вот решение.
Следующий синтаксис Bash скроет вывод к stdout, но все еще покажет stderr. Сначала мы передаем stdout по каналу к/dev/null, затем мы преобразовываем stderr в stdout, потому что каналы Unix будут только воздействовать на stdout. Вы можете все еще grep текст.
$ ./stdout-stderr.sh 2>&1 >/dev/null | grep err
./stdout-stderr.sh: Printing to stderr
(Обратите внимание, что вышеупомянутая команда отличается затем ./command >/dev/null 2>&1
, который является очень общей командой).
Вот сценарий, используемый для тестирования. Это печатает одну строку к stdout и одну строку к stderr:
#!/bin/sh
# Print a message to stdout
echo "$0: Printing to stdout"
# Print a message to stderr
echo "$0: Printing to stderr" >&2
exit 0
./stdout-stderr.sh 2>&1 >/dev/null | grep err
.
– Mikel
08.02.2011, 03:45
Когда Вы передаете вывод по каналу одной команды другому (использование |
), Вы только перенаправляете стандартный вывод. Таким образом, это должно объяснить почему
ffmpeg -i 01-Daemon.mp3 | grep -i Duration
не производит то, что Вы хотели (это действительно работает, хотя).
Если Вы не хотите перенаправлять вывод ошибок к стандартному выводу, можно перенаправить вывод ошибок в файл, то grep он позже
ffmpeg -i 01-Daemon.mp3 2> /tmp/ffmpeg-error
grep -i Duration /tmp/ffmpeg-error
it does work, though
, Вы подразумеваете, что это работает над Вашей машиной? Во-вторых, поскольку Вы указали на канал использования, мы можем только перенаправить stdout. Я интересуюсь некоторой командой или функцией удара, которая позволит мне перенаправить stderr. (но не временный прием файла)
– Andrew-Dufresne
26.10.2010, 07:07
попробуйте эту команду
Чева-> просто имя переменной (английский язык = что-то)
ceva=$RANDOM$RANDOM$RANDOM; ffmpeg -i qwerty_112_0_0_record.flv 2>$ceva; cat $ceva | grep Duration; rm $ceva;
Вариант примера подпроцесса bash:
выведите две строки в stderr и tee stderr в файл, grep тройник и труба обратно на stdout
(>&2 echo -e 'asdf\nfff\n') 2> >(tee some.load.errors | grep 'fff' >&1)
stdout:
fff
some.load.errors (например, stderr):
asdf
fff
Вы можете поменять потоки местами. Это позволит вам grep
оригинальный поток стандартной ошибки, получая при этом вывод, который изначально шел на стандартный вывод в терминале:
somecommand 3>&2 2>&1 1>&3- | grep 'pattern'
Это работает путем создания нового файлового дескриптора (3), открытого для вывода, и установки его на поток стандартной ошибки (3>&2
). Затем мы перенаправляем стандартную ошибку на стандартный вывод (2>&1
). Наконец, стандартный вывод перенаправляется на исходную стандартную ошибку, а новый дескриптор файла закрывается (1>&3-
).
В вашем случае:
ffmpeg -i 01-Daemon.mp3 3>&2 2>&1 1>&3- | grep -i Duration
Проверяем:
$ ( echo "error" >&2; echo "output" ) 3>&2 2>&1 1>&3- | grep "error"
output
error
$ ( echo "error" >&2; echo "output" ) 3>&2 2>&1 1>&3- | grep -v "error"
output
В этом случае мне нравится использовать оболочку rc
.
Сначала установите пакет (, он меньше 1 МБ ).
Это пример того, как вы можете отбросить stdout
и передать stderr
для grep вrc
:
find /proc/ >[1] /dev/null |[2] grep task
Вы можете сделать это, не выходя из Баша:
rc -c 'find /proc/ >[1] /dev/null |[2] grep task'
Как вы могли заметить, синтаксис прост, поэтому я предпочитаю это решение.
Вы можете указать, какой дескриптор файла вы хотите передать в квадратных скобках, сразу после символа вертикальной черты.
Стандартные файловые дескрипторы нумеруются соответственно:
bash
может перенаправлять поток stdout в поток stdin через обычный конвейер-|
Он также может перенаправлять как stdout, так и stderr на stdin с помощью|&
cp
выводcp -r dir* to 2> >(grep -v "svn")
– Betlista 15.08.2014, 17:08>&2
, например.command 2> >(grep something >&2)
– tlo 06.05.2016, 12:16