Назад | Перейти на главную страницу

Запуск скрипта в фоновом режиме без привязки к оболочке

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

Пример: запускаю скрипт run1.sh:

#!/bin/sh
function logpipe() {
    while read line;do
        echo $line >> $1
    done
}

./bin/run2.sh $JBOSS_HOSTNAME | logpipe $JBOSS_DIST/log/server.log 2>&1 &

run2.sh:

#!/bin/sh
exec "$JAVA" -DJBOSS_PID=_$$_ $JAVA_OPTS \
         -Djava.endorsed.dirs="$JBOSS_ENDORSED_DIRS" \
         -classpath "$JBOSS_CLASSPATH" \
         org.jboss.Main "$@"

Теперь проблема в том, когда я бегу

ssh myhost "bin/run1.sh"

оболочка «застревает» в скрипте, и я могу избавиться от нее, только закрыв ее с помощью Crtl + C. Я предполагаю, что это что-то среднее между nohup и другим трюком с трубопроводом, но я просто не мог до него добраться.

Вам следует попробовать запустить свой сценарий в "экран".

screen -D -m run1.sh

А затем вы можете догнать экран:

screen -r

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

с помощью nohup просто сообщает оболочке, что если внешний объект отправляет сигналы зависания, их следует игнорировать, но на самом деле это не отключает программу от консоли.

В любом случае, я не знаю, как явно отключать программу от терминала, но вы можете отправить сигнал HUP в сеанс SSH, который запустил сценарий, используя команду

kill -HUP $PPID

это завершит соединение SSH и оставит программу работающей, но вызывающий клиент ssh получит уродливое сообщение об ошибке «соединение закрыто удаленным хостом».

В дополнение к ssh -t, упомянутому выше, который, я думаю, будет работать, вы должны обязательно закрыть все входы и выходы вашего скрипта:

ssh myhost "bin/run1.sh > yourlog 2>&1 < /dev/null"

Все кредиты FAQ по OpenSSH, где Я нашел это много лет назад.

Я считаю, что вы правы насчет nohup. В run1.sh попробуйте изменить последнюю строку на:

nohup ./bin/run2.sh $JBOSS_HOSTNAME | logpipe $JBOSS_DIST/log/server.log 2>&1 &
ssh myhost "nohup bin/run1.sh"

Должен сделать свое дело.

Что произойдет, если исходники run1.sh run2.sh ?:

. ./bin/run2.sh $JBOSS_HOSTNAME | logpipe $JBOSS_DIST/log/server.log 2>&1 &

Скорее всего, все еще открыты файловые дескрипторы fd> 2. Проверьте с lsof.