Условное выполнение – запуск постоянных подпроцессов и коротинов

Условное выполнение используется в Bash для управления потоком скрипта на основе состояния выхода подпроцесса. Однако бывают ситуации, когда подпроцесс (приложение) запускается в фоновом режиме, для использования в интерактивных целях, поэтому нет выхода и статуса выхода, пока он не будет закрыт.

Рассмотрим несколько примеров, например, запуск программы просмотра pdf, mupdf . Рассмотрим первый случай с файлом, который существует, example.pdf:

$ mupdf example.pdf & [1] 16220 

Это работает, поэтому давайте попробуем условное выполнение:

 $ mupdf example.pdf & && echo TRUE bash: syntax error near unexpected token '&&' 

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

 $ if mupdf example.pdf &; then echo TRUE; fi bash: syntax error near unexpected token ';' 

Как насчет:

 $ if (mupdf example.pdf &); then echo TRUE; fi TRUE 

Это выглядит многообещающим, но потом мы попробуем второй случай с файлом, которого нет:

 $ mupdf nofile.pdf & [1] 16282 $ error: cannot open nofile.pdf error: cannot load document 'nofile.pdf' mupdf: error: cannot open document $ if (mupdf nofile.pdf &); then echo TRUE; fi TRUE $ error: cannot open nofile.pdf error: cannot load document 'nofile.pdf' mupdf: error: cannot open document 

Эта конструкция тоже не работает. Таким образом, обычный подход к условному исполнению не работает, потому что нет статуса выхода. Но я заметил, что pid изначально создается как в успешных, так и в неудачных случаях ( mupdf не открывается во втором случае – запуск в конечном итоге не удается).

Поэтому попробуйте другой подход, подождите, чтобы узнать, что происходит с фоном pid, поэтому мы собрали следующий скрипт:

 #!/usr/bin/env bash # usage: ./show <file>.pdf mupdf "$1" &>/dev/null & sleep 2 if kill -0 $! &>/dev/null then echo TRUE else echo FALSE fi # end file 

И проверьте первый случай:

 $ ./show example.pdf # case 1 [1] 16602 TRUE 

Ничего страшного. Теперь второй случай:

 $ ./show nofile.pdf # case 2 [2] 16699 [2]+ Exit 1 mupdf nofile.pdf &> /dev/null FALSE 

Ну, это тоже работает. Но это кажется очень запутанным способом проверить процесс и может потерпеть неудачу, если запуск занимает больше времени (более 2 секунд). Итак, мой вопрос становится, есть ли лучший (более чистый) способ решить эту проблему?

One Solution collect form web for “Условное выполнение – запуск постоянных подпроцессов и коротинов”

Я нашел несколько подобных тем, которые рассматривают использование таких вещей, как xdotool и wmctl, для тестирования запуска стойкого оконного приложения или другого постоянного подпроцесса . Но использование их кажется ненужным осложнением. Приведенное ниже решение разрешило бы условное выполнение постоянного подпроцесса. Он использует продолжительность сна в полсекунды. Если для подпроцесса, представляющего интерес, потребуется больше времени для успешного запуска, тогда эта продолжительность должна быть соответственно увеличена.

Запуск исходного файла Bash

 #/usr/bin/env bash # launch : will allow launching a windowed application or persistent # sub-process in the background so that conditional execution can be # applied to determine whether or not it has launched successfully - # dependencies: GNU coreutils (sleep), util-Linux (kill) # usage: ./launch process arg_1 .. arg_n && echo TRUE || echo FALSE $@ &>/dev/null & sleep 0.5 && kill -0 $! 2>/dev/null # end file 

Так что:

 $ ./launch mupdf example.pdf && echo TRUE || echo FALSE TRUE $ ./launch mupdf nofile.pdf && echo TRUE || echo FALSE FALSE 

В качестве постобработки этой информации я подумал, что было бы полезно включить совет mikeserv в комментарии к открытому сообщению.

В то время как вышеупомянутая конструкция выполняет непосредственную задачу, mikeserv указывает, что это может привести к другим проблемам в том, что она не передает сигнал вызывающему сценарию; он вместо этого игнорирует и отбрасывает его. Это очень важное замечание.

Сигналы являются ключевым элементом межпроцессного взаимодействия и могут приводить к возможности сценариев, управляемых событиями. Таким образом, для более надежных и эффективных скриптов mikeserv предлагает следующее, чтобы поймать сигнал, чтобы он мог распространяться:

 { mupdf some.pdf || kill -"$(($?&127))" "$$"; } & 

где $?&127 разрешает действие от 1 до 128 возможных сигналов (POSIX), моя система Debian имеет 64, поэтому сигнальная маска может быть вместо $?&63 .


Итак, в качестве заключительного замечания, для очень простых сценариев, где межпроцессное общение не представляет интереса, предлагаемый запуск может быть полезен, но для чего-то большего, особенно там, где важна взаимосвязь между процессами , захватывать (и распространять) сигнал, как советовал mikeserv ,

  • Проверка наличия программного обеспечения в сеансе SSH
  • Печать переменной в одиночной кавычки в bash | Странные переменные
  • Сценарий оболочки для записи выбранных полей в одну строку
  • Возникли проблемы с базовым, если это утверждение
  • Объединение папок с одним и тем же именем, но с другим корпусом
  • Автоматизация ввода текста в команду из сценария bash
  • Напишите на n-ю строку терминала без переписывания всего остального
  • Поведение команды отличается при выполнении другим пользователем (через su -c)
  • Использование grep для поиска подстроки между двумя строковыми переменными, которые содержат пути
  • получить имя нового каталога, созданного из команды tar
  • Как найти слово и удалить его со следующей строкой
  • Linux и Unix - лучшая ОС в мире.