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


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.