[ 3 -gt "$(ps -Aocomm=|grep -c ADM)" ] &&
mail -s xxxx.gmail.com <<MAIL
AdmServer is down on Dev $hostname
MAIL
Я думаю, что приведенная выше команда должна работать как замена вашей.
При запуске не -в интерактивном режиме (, например. в сценарии )bash отключает управление заданиями, поэтому простые методы уничтожения фоновых процессов, например, в Убить все фоновые задания или Как убить все задания в bash? по умолчанию не работает.
Первое, что я хотел бы сделать, это убедиться, что вы используете bash, изменив строку sh -bang на:
#!/bin/bash
Затем давайте включим управление заданиями (, также известное как «режим монитора» ), чтобы мы могли использовать одно из простых решений из предыдущих вопросов:
set -m
Затем я бы упростил большую часть вашей работы с подоболочкой; они вам не нужны. С упрощенными командами, просто чтобы продемонстрировать суть:
#wait 10 seconds before starting nav and rviz otherwise will get error
sleep 10 || exit
terminator -T "navigation... bash" &
terminator -T "rviz... bash" &
...
terminator -T "spawn_objects_launch" &
echo Press any key to to shutdown all processes
read varname
echo Shutting down...
Вам не нужно запускать всю подоболочку (и запускать ее в фоновом режиме )для всех процессов-терминаторов. Вам не нужно запускать sleep 10
в подоболочке. Вам не на самом деле нужно проверять код возврата sleep 10
, чтобы связать последующие команды с &&
. Я адаптировал код, чтобы он соответствовал существующему поведению :, если команда sleep дает сбой (, скажем, вы нажали Control -C ), тогда сценарий завершится и не запустит последующие процессы терминатора.
Наконец, добавьте код для уничтожения дочерних процессов:
...
terminator -T "spawn_objects_launch" &
echo Press ENTER to shutdown all processes
read
echo Shutting down...
kill $(jobs -p)
Я перефразировал подсказку; вам нужно будет ввести (почти )любую клавишу, а затем нажать ENTER, чтобы команда read
увидела ваш ввод, поэтому я просто предлагаю пользователю нажать ENTER. Следующий,команда read
принимает имя переменной, но есть переменная по умолчанию с именем REPLY
, которую она будет использовать, если вы не укажете свое собственное имя переменной, поэтому, в зависимости от того, более ли это для вас очевидно, это еще один вариант упрощения код.