То, что awk system ()
должна возвращать , плохо определено .
Что, по-видимому, является общим для реализаций awk
, так это то, что при нормальном выходе он возвращает код выхода (число, переданное в exit (3)
по модулю 256), но когда процесс оболочки завершается сигналом, есть много другого поведения.
Также обратите внимание, что хотя функция C system (3)
предназначена для игнорирования SIGINT (и SIGQUIT) в родительском элементе, не очень ясно (по крайней мере для меня), что это требование также применяется к awk
система ()
. Некоторые реализации awk
(например, mawk
) умрут после этого SIGINT (это тоже поведение, которое я хотел бы видеть, поскольку мне не нравится, что мой CTRL-C игнорируется только потому, что awk
выполняет функцию system ()
), некоторые (например, gawk
или традиционные реализации) - нет.
Также обратите внимание, что некоторые оболочки могут перехватывать некоторые из этих сигналов и в конечном итоге вызывать exit ()
, что может повлиять на поведение (см. Обсуждение в комментариях, например, об оболочке Bourne), поэтому я использую exec
в примерах ниже, чтобы удалить оболочку из цикла.
Для значения, возвращаемого функцией system ()
(есть еще большее разнообразие, если учесть close ()
1 ) при SIGINT, мы видим:
$ nawk 'BEGIN {print system("exec kill -s INT $$")}'
0.0078125
$ bwk-awk 'BEGIN {print system("exec kill -s INT $$")}'
0.0078125
$ mawk 'BEGIN {print system("exec kill -s INT $$")}'
130
$ gawk 'BEGIN {print system("exec kill -s INT $$")}'
0
0,0078125
составляет 2/256
(для SEGV
из 11
, вы получите 0,542969 ((128 + 11) / 256), если ядро было сброшены, 0.0429688 (11/256) в противном случае), nawk
- это nawk
, найденный в Solaris 10 или 11, или его порт Linux в инструментарии Heirloom, bwk-awk
awk
, поддерживаемый самим Брайаном Керниганом ( K
в awk
), основа для найденного awk
на некоторых BSD (здесь проверено на Debian GNU / Linux). / usr / xpg4 / bin / awk
в Solaris 11 ведет себя как gawk
.
Таким образом, на основе значения s
, возвращенного system (3)
(целое число, где биты от 0 до 6 - это номер сигнала, бит 7 - базовый бит, а биты 8 до 15 код выхода), awk
system ()
выше возвращает либо:
s / 256
(традиционные реализации awk
), int (s / 256)
( gawk
), mawk
, то же преобразование, которое выполняется оболочками, такими как Bourne или C-shell для экземпляр ( (s & 127) +128
в случае убийства, s >> 8
в противном случае), за исключением того, что если ядро выгружено, вы получите (s & 127) +256
вместо (s & 127) +128
(значение (s & 255) +128
). Итак, здесь вы можете сделать вместо этого:
awk 'BEGIN{print system("trap exit\\ 1 INT; sleep 10")}'
Но это все равно приведет к уничтожению awk
некоторыми реализациями awk
, такими как mawk
. Если ваш sh
равен bash
или yash
, вы можете сделать:
awk 'BEGIN{print system("set -m; sleep 10; exit")}'
Итак, sleep
запускается в своей собственной группе процессов (и только он получает СИГНАЛ).
Другой альтернативой может быть игнорирование SIGINT перед вызовом awk
. Однако большинство оболочек (и это требование POSIX) не может изменить обработчик сигнала, если сигнал уже был проигнорирован при запуске. Так что такие вещи, как:
(
trap '' INT
awk 'BEGIN{print system("trap exit\\ 1 INT; sleep 10; exit")}'
)
Не сработают. zsh
не имеет этого (самовольного) ограничения, поэтому, если вы знаете, что zsh
доступен, вы можете сделать:
(
trap '' INT
awk 'BEGIN{print system("exec zsh -c \"TRAPINT() exit 1; sleep 10\"")}'
)
Что будет работать, если awk
- это mawk
, gawk
или другое, что позволит избежать путаницы с управлением заданиями. Однако на этом этапе стоит рассмотреть возможность использования perl
/ python
/ ruby
...вместо awk
, где вы можете адаптировать обработку сигналов к вашим потребностям.
1 После close ()
конвейера, например:
awk 'BEGIN {cmd = "kill -s INT $$"; cmd | getline; print close(cmd)}'
Сначала, на этот раз ^ C
прерывает awk
во всех реализациях, которые я пробовал (нет такого требования игнорировать SIGINT / SIGQUIT для popen (3)
/ pclose (3)
(естественный способ реализовать это ) getline
), как и для системы (3)
).
Но когда дело доходит до статуса выхода (где s
- это значение, возвращаемое pclose (3)
/ waitpid (2)
как для ] system ()
выше), мы видим:
nawk
: не работает, вы не можете вызвать close ()
, как в Solaris ] nawk
. / usr / xpg4 / bin / awk
в Solaris. Всегда возвращает 0, даже после exit (1)
, выполненного процессом. Явно ошибка соответствия. gawk
и bwk-awk
: дает s
( выход 1
дает 256, убит SIGINT дает 2, убит SIGSEGV 11 с ядром дает 139). mawk
: то же самое, что и для system ()
, похоже, что mawk
- единственная реализация, которая об этом задумалась. Не знаю, что после этого делает большинство администраторов, но могу рассказать, что я делаю перед выполнением чего-то подобного :Я ищу пакет для дистрибутива, который намереваюсь использовать, и если не нахожу один, удовлетворяющий моим требованиям, либо
Но это я, и мне абсолютно все равно, подписан этот программный пакет или нет. Моя модель угроз включает в себя разработчиков программного обеспечения, особенно если я могу быть уверен, что ни один дистрибьютор никогда не смотрел на программное обеспечение.
but there should be a move away from this curl installation pattern.
Да. Там должно. Но его нет, и я могу понять разработчиков программного обеспечения, предлагающих такой способ установки, поскольку создавать пакеты для всех соответствующих дистрибутивов Linux и трех или четырех BSD — отстой. Это отстой даже хуже, чем это было 15 лет назад.
Как правило, curl URL(script) | sh
загружает и выполняет сценарий оболочки (сценарий установки ), это автоматизированный сценарий для простой установки программы, он выполняет некоторые задачи, например :проверка зависимостей, создание/удаление каталогов, запрос пароля root, добавление репозиториев, загрузка соответствующей версии программы в ваш дистрибутив Linux...
The best practices before executing the install script.
curl url(script)
cat
, less
...)sudo bash script
, sudo sh script
... Это пример скрипта bash для установки node.js :curl -sL https://deb.nodesource.com/setup_9.x
, который содержит инструкции по использованию.
The best practices after executing the install script.
После выполнения сценария установки программа будет установлена в вашей системе. Если сценарий установки не включает способ обновления программы (, репозиторий для автоматического применения обновлений через диспетчер пакетов, задание cron... ), лучше проконсультироваться на веб-странице -сопровождающий.