Штриховой эквивалент самонаправления вывода скрипта

9

В Bash вы можете перенаправить весь будущий вывод stdout текущего запущенного скрипта. Например, с этим сценарием,

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3

Это закончится в системном журнале:

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3

Но это специфично для Bash, и голый exec с перенаправлением, похоже, не работает в Dash.

Syntax error: redirection unexpected

Как я могу заставить его работать в Dash или, возможно, в обеих оболочках?

Алекс Б
источник
Не могли бы вы уточнить, что именно вам нужно? Вы можете перенаправить с помощью >тире. Я понимаю, что вы, кажется, просите что-то еще, но я не могу точно сказать, что это.
Terdon
@terdon Я расширил объяснение.
Алекс Б

Ответы:

6

Вы можете просто сделать:

{ commands
....
} | logger -t my_awesome_script

Вы можете сделать это с любой оболочкой.

Если вам не нравится, как он выглядит, возможно, заставьте скрипт обернуть себя в функцию.

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff
mikeserv
источник
Эта последняя строка должна быть run ${1+"$@"} || do stuffтаковой, чтобы аргументы были сохранены.
Адам Кац
@AdamKatz - хороший момент, execpt ${1+"$@"}ничего "$@" не делает . В любом случае, у него были другие проблемы.
mikeserv
"$@"пройдет, ""когда нет аргументов, пока ${1+"$@"}пропустит пустую строку, когда нет аргументов. Это очень важно для многих программ, так как они анализируют ""как пустой аргумент, в то время как пустая строка (без кавычек) вообще не будет интерпретироваться как аргумент.
Адам Кац
@AdamKatz - очень старая оболочка Bourne могла бы (и я не ожидал бы найти dashв такой системе) , но в остальном "$@"уникальна в том, что случай с нулевым аргументом не заменяет нулевой аргумент для оболочек POSIX.
mikeserv
1
@AdamKatz - это была ошибка даже в старом bsh, и она никогда не должна была работать так. Это было в конечном счете исправлено, но я не знаю, должно ли это все еще быть необходимым в Солярисе 10, например. Youre право около $ * - оно не обладает теми же аккуратными свойствами expabsion - его уникальность onky относится к переменному содержанию его расширения, хотя она всегда будет something.in моего взгляда, "${@+is especially cool $@}" . Но практически не отличается от старого ${1+”$@"}обходного пути в конце концов. Если у вас есть ksh93:"${1+quoted" not quoted "quoted again}"
mikeserv
5

Замена процесса легко моделируется с помощью именованных каналов.

mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3

На самом деле, именованные каналы - это один из механизмов (другой /dev/fd), с помощью которых может быть реализовано замещение процесса bash.

chepner
источник
Наиболее универсальный, на мой взгляд: я мог бы использовать тройник для плавного перенаправления на несколько потоков. Только одно: не забудьте удалить созданный logger_input в конце скрипта.
Lauhub
2

Я не думаю, что это возможно в dash. Насколько я могу судить по его manстранице , он не поддерживает подстановку процессов.

В качестве обходного пути вы можете попробовать то, что предложил mikserv , или вы можете перенаправить все в файл, а затем, после того как ваш скрипт будет завершен (предположительно, это в скрипте), добавить содержимое этого файла в logger:

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script
Тердон
источник
На самом деле, замена процесса - или то, что другие оболочки называют заменой процесса - легче в dashдругих оболочках. Подстановка процесса - это просто аргумент, указывающий на /dev/fd/[num]ссылку на анонимный канал. dashделает здесь документы с анонимными каналами, а не с временными файлами genning, как большинство других оболочек. Так что cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\nэто не только функционально эквивалентно, вы даже можете назвать имя FD самостоятельно. Тем не менее, ваша точка зрения направлена ​​на то, чтобы пойти по другому пути - вам нужно открыть новый файл с помощью execи запустить процесс, который его читает.
mikeserv
2
@mikeserv: В каком смысле cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n«легче», чем cat <(get output)?
Руах
@mikeserv: здесь нужно помнить множество правил; возможно, вы просто настолько привыкли к ним, что не замечаете.
Руах
@ruakh - ну конечно. < >перенаправления оболочки. в основном, если вы просто сделаете два из них, то сможете добавить и следующие строки. Но да, у вас есть точка зрения - мне здесь нравятся документы. Тем не менее, так много вещей, которые могут потребовать запоминания, мне кажется, легче, когда они работают универсально. С другой стороны, многим людям не очень нужны другие оболочки, и для них это не имеет значения. Я просто не среди них.
mikeserv
1
@mikeserv: Не только heredocs, но также /dev/fd/3(в этой точной форме) и детали того, что происходит с пробелами. , , и в этом отношении тот факт, что весь этот подход работает вообще в Dash, когда он не работает в других оболочках, которые имеют все компоненты, означает, что общий подход - это особое правило, которое нужно запомнить. (Это напоминает мне о попытках создать упрощенный английский с меньшим словарным запасом; они вырезают такие слова, как « сохраняй» , но игнорируют такие же сложные идиомы, как « продолжай» .)
ruakh,