Скажем, у нас есть скрипт bash, например:
echo "x" &
echo "y" &
echo "z" &
.....
echo "Z" &
wait
Есть ли способ собрать коды выхода для вложенных оболочек / подпроцессов? Ищите способ сделать это и ничего не можете найти. Мне нужно запустить эти подоболочки параллельно, иначе да, это будет проще.
Я ищу общее решение (у меня есть неизвестное / динамическое число подпроцессов для параллельной работы).
bash
shell-script
shell
subshell
Александр Миллс
источник
источник
Ответы:
Ответ Александра Миллса, который использует handleJobs, дал мне отличную отправную точку, но также дал мне эту ошибку
Что может быть проблемой состояния гонок bash
Вместо этого я просто сохранял pid каждого ребенка и ждал, и получал код выхода для каждого ребенка отдельно. Я нахожу это более чистым с точки зрения подпроцессов, порождающих подпроцессы в функциях и избегающих риска ожидания родительского процесса, в котором я намеревался дождаться потомка. Понятно, что происходит, потому что ловушка не используется.
источник
for job in "${childen[@]}"; do
должно быть,for job in "${1}"; do
хотя, для ясностиchildren_pids+=("$!")
фактически захват желаемого pid для вложенной оболочки.Используйте
wait
с PID, который будет:Вам нужно будет сохранять PID каждого процесса по ходу:
Вы также можете включить управление заданиями в сценарии
set -m
и использовать%n
спецификацию заданий, но вы почти наверняка этого не захотите - контроль заданий имеет много других побочных эффектов .wait
вернет тот же код, что и процесс, завершенный. Вы можете использоватьwait $X
в любой (разумный) момент для доступа к окончательному коду$?
или просто использовать его как true / false:wait
будет приостанавливаться до тех пор, пока команда не завершится, если это еще не сделаноЕсли вы хотите , чтобы избежать срыва , как это, вы можете установить
trap
наSIGCHLD
, подсчитывают количество окончаний, и обрабатывать всеwait
с на один раз , когда они уже все закончили. Вы можете, вероятно, сойти с рук вwait
одиночку почти все время.источник
wait $X
в любой (разумный) более поздний момент.Если у вас есть хороший способ идентифицировать команды, вы можете напечатать их код выхода в файл tmp, а затем получить доступ к конкретному файлу, который вас интересует:
Не забудьте удалить файлы tmp.
источник
Используйте
compound command
- поставьте оператор в скобках:даст выход
Действительно другой способ запустить несколько команд параллельно - это использовать GNU Parallel . Составьте список команд для запуска и поместите их в файл
list
:Запустите все команды параллельно и соберите коды выхода в файле
job.log
:и вывод:
источник
PIPESTATUS
вам стоит это проверить. Этоseq 10 | gzip -c > seq.gz ; echo ${PIPESTATUS[@]}
возвращает0 0
(код выхода из первой и последней команды).это общий сценарий, который вы ищете. Единственным недостатком является то, что ваши команды заключены в кавычки, что означает, что подсветка синтаксиса через вашу среду IDE не будет работать. В противном случае, я попробовал пару других ответов, и это лучший. Этот ответ включает в себя идею использования
wait <pid>
данных @Michael, но идет дальше, используяtrap
команду, которая, кажется, работает лучше всего.спасибо @michael homer за то, что я выбрал правильный путь, но использование
trap
команды - лучший подход AFAICT.источник
Еще один вариант ответа @rolf:
Еще один способ сохранить статус выхода будет что-то вроде
а затем каждый сценарий
Это дает вам уникальное имя для каждого файла состояния, включая имя сценария, который его создал, и его идентификатор процесса (в случае, если запущено более одного экземпляра одного и того же сценария), которое вы можете сохранить для справки позже, и помещает их все в то же самое место, так что вы можете просто удалить весь подкаталог, когда вы закончите.
Вы даже можете сохранить более одного состояния из каждого сценария, выполнив что-то вроде
который создает файл, как и раньше, но добавляет к нему уникальную случайную строку.
Или вы можете просто добавить больше информации о состоянии в тот же файл.
источник
script3
будет выполнен только в том случае, еслиscript1
иscript2
успешно,script1
иscript2
будет выполняться параллельно:источник