Тире еквівалент самонаправлення виводу сценарію


9

У Bash ви можете перенаправити весь майбутній вихід stdout поточного запущеного сценарію. Наприклад, із цим сценарієм,

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

Це закінчиться в syslog:

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, і голий виконавець із перенаправленням, здається, не працює в Dash.

Syntax error: redirection unexpected

Як я можу змусити його працювати в тирі чи, можливо, в обох оболонках?


Чи можете ви уточнити, що саме вам потрібно? Ви можете переспрямувати >на тире. Я усвідомлюю, що ти, здається, просиш щось інше, але я не можу повністю сказати, що це таке.
тердон

@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

Цей останній рядок повинен бути run ${1+"$@"} || do stuffтаким, щоб аргументи зберігалися.
Адам Кац

@AdamKatz - добре, execpt ${1+"$@"}нічого "$@" не робить . У нього все одно були інші проблеми.
mikeserv

"$@"пройде, ""коли аргументів немає, тоді як ${1+"$@"}пройде порожня рядок, коли аргументів немає. Це надзвичайно важливо для багатьох програм, оскільки вони розбираються ""як порожній аргумент, тоді як (без котирування) порожній рядок взагалі не трактується як аргумент.
Адам Кац

@AdamKatz - дуже стара оболонка Bourne, можливо, (і я не сподівався би знайти dashв такій системі) , але в іншому випадку "$@"вона унікальна тим, що випадок нульових аргументів не замінює нульовий аргумент для оболонок POSIX.
mikeserv

1
@AdamKatz - це насправді помилка навіть у старому bsh і ніколи не повинен був так працювати. Врешті-решт це було зафіксовано, але я не знаю, чи все-таки це потрібно, наприклад, у Solaris 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.


Найбільш універсальний на мій погляд: я міг би використати трійник для перенаправлення на кілька потоків. Тільки одне: не забудьте видалити створений logger_input наприкінці сценарію.
lauhub

2

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

Як вирішення, ви можете спробувати те, що запропонував mikserv , або ви можете перенаправити все до файлу, а потім після завершення сценарію (імовірно, це в сценарії), додайте вміст цього файлу до реєстратора:

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script

Насправді, заміщення процесу - або те, що інші оболонки називають процес заміщення - легше, dashніж інші оболонки. Заміна процесу просто означає аргумент, який вказує на /dev/fd/[num]посилання на анонімну трубку. dashробить тут документи з анонімними трубами, а не генерування тимчасових файлів, як це робить більшість інших оболонок. Отже, cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\nце не лише функціонально рівнозначно, ви навіть можете назвати FD самостійно. Тим не менш, ваша думка добре зроблена щодо того, щоб піти іншим шляхом - вам потрібно відкрити новий FD з execфоном і прочитати процес, який його читає.
mikeserv

2
@mikeserv: У якому сенсі cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"простіше", ніж cat <(get output)?
ruakh

@mikeserv: Це включає в себе безліч правил, які слід пам'ятати; можливо, ви просто так звикли до них, що не помічаєте.
ruakh

@ruakh - ну точно. < >перенаправлення оболонок в основному, якщо ви просто зробите два з цих, ви можете також складати на наступних рядках. Але так, у вас є пункт - мені тут подобаються документи. І все-таки, як багато речей, можливо, потребує запам'ятовування, простіше, коли вони працюють універсально, я думаю. Тоді знову багато людей не мають великої користі для інших снарядів, і це не має для них ніякого значення. Я просто не серед них.
mikeserv

1
@mikeserv: Не лише гередоки, але також /dev/fd/3(у такій точній формі) та деталі того, що відбувається з пробілом. . . і, з цього приводу, той факт, що весь цей підхід працює взагалі в Dash, коли він не працює в інших оболонках, у яких є всі компоненти, означає, що загальний підхід - це особливе правило, яке слід пам'ятати. (Це нагадує мені про спроби створити спрощену англійську мову з меншою кількістю словникових запасів; вони вирізали такі слова, як наполягають , але вони ігнорують так само складні ідіоми, як продовжувати .)
ruakh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.