Как вы поддерживаете этот подлый сценарий bash, работающий в фоновом режиме 24/7?

В

cmd1 | cmd2

cmd1и cmd2запускаются параллельно с stdout cmd1подключенным к записывающему концу канала (или пары сокетов в ksh93 ), а stdin cmd2подключен к другому концу ту трубу.

В:

cmd < file

cmdзапускается с cmdstdin, открытым на file.

Итак, вы видите, что

cmd1 | cmd2 < file

конфликты; вам нужно выбрать, является ли stdin cmd2каналом из cmd1или file.

В приведенном выше примере в большинстве оболочек <fileимеет приоритет, так как перенаправление выполняется после(оболочка запускает 2 процесса с каналом в -между ними, и , затем интерпретирует каждую из команд, включая перенаправления внутри каждой независимо)

Это означает, что стандартный ввод cmd2будет file, а канал echo, в который выполняется запись, не будет иметь читателя (сломанного канала ). Таким образом, в вашем случае barникогда не доберется до nc, а процесс, выполняющий echo bar, может даже быть убит, если он напишет barпосле того, как другой процесс открыл файл.

Однако в zshс опцией multiosв (и включенной по умолчанию )zshобнаруживает, что вы пытаетесь перенаправить тот же файловый дескриптор (сюда 0, stdin )дважды и принимает то, что вы имели в виду, чтобы данные из обоих этих источников были отправлены в cmd2, поэтому вместо того, чтобы делать cmd2stdin каналом из cmd1или file, он фактически запустить внутренний фидерный процесс , который считывает данные из обоих источников и отправляет их (один за другим через другой канал )в cmd2.

cmd1 < <(cmd2)

— это просто случай cmd1 < file, где file— это именованный канал (или что-то, что ведет себя как именованный канал )с записью cmd2на другом конце, но в остальном не сильно отличается.

Переносимо, если вы хотите отправить вывод двух команд,или отправить вывод команды и содержимое файла какой-либо команде, вы должны использовать:

{
  cmd1
  cmd2
} | cmd3

Или:

{
  cmd1
  cat < file
} | cmd2

Так вот:

{
  echo bar
  echo foo
} | nc localhost 6969
0
14.04.2020, 21:02
2 ответа

Программы, которые полагаются на ввод, как вы описали, должны запускаться внутри терминального мультиплексора, такого какtmux(https://en.wikipedia.org/wiki/Tmux)или screen(https://www.gnu.org/software/screen/). Думайте об этом как о текстовой -версии окна терминала.

Используйте screen my-programдля запуска my-program. Затем вы можете отсоединить от консоли виртуального экрана, используя комбинацию клавиш -штрихов Ctrl-ACtrl-D , и вы вернетесь к оболочки, с которой вы начали, но ваша программа продолжает работать в фоновом режиме. Затем с помощью screen -rвы можете повторно подключиться к виртуальной консоли.

Экран

(, и ваша программа )будет продолжать работать до тех пор, пока вы не завершите работу программы или сервер не будет перезагружен.

tmuxочень похож, но имеет больше параметров и функций и использует другие сочетания клавиш.

1
19.03.2021, 02:29

Чтобы скрипт продолжал работать в фоновом режиме, используйте nohup:nohup scriptcommand &. В идеале сценарий должен иметь возможность не запрашивать ввод. Если по какой-то причине это невозможно, можно использовать Expect для ввода 'y'.

Создание службы systemd для скрипта позволит запускать скрипт при перезагрузке системы. Вы также можете использовать Restart=alwaysв вашем файле systemd для перезапуска службы, если служба была закрыта или убита, документация systemd содержит дополнительную информацию .

0
19.03.2021, 02:29

Теги

Похожие вопросы