Запуск сценария SSH с фоновым процессом - PullRequest
0 голосов
/ 28 апреля 2018

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

test.sh

#!/bin/bash

(
sleep 2 
echo "done"
) &

Когда я запускаю скрипт на консоли, он сразу же возвращается, и через 2 секунды появляется «готово».

Когда я запускаю скрипт как скрипт ssh, команда ssh. Похоже, он ожидает завершения всех дочерних процессов, пока не выйдет ssh.

ssh пример

$ ssh mike@127.0.0.1 /home/mike/test.sh
(2 seconds)
done

пример стандартного терминала

$ ./test.sh
$ 
(2 seconds)
done

Как сделать так, чтобы ssh возвращал, когда родительский / основной процесс завершился?

EDIT:

Мне известна опция -f в ssh для запуска процесса в фоновом режиме. Он оставляет процесс ssh и соединение открытым на исходном хосте. Для моих целей это не подходит.

1 Ответ

0 голосов
/ 30 апреля 2018
ssh mike@127.0.0.1 /home/mike/test.sh

Когда вы запускаете ssh таким способом, удаленный ssh-сервер создаст набор каналов (или пар сокетов), которые станут стандартным вводом, выводом и ошибкой для процесса, который вы запустили, в этом случае сценарий процесс. Сервер ssh не завершает сеанс в зависимости от того, когда завершается процесс сценария. Вместо этого он завершает сеанс при чтении и указании конца файла в стандартном выводе процесса сценария и стандартной ошибке.

В вашем случае процесс сценария создает дочерний процесс, который наследует стандартный ввод, вывод и ошибку сценария. Канал (или пара сокетов) возвращает EOF, только когда все возможные авторы завершили или закрыли свой конец канала. Пока дочерний процесс выполняется и имеет копию стандартных дескрипторов файла вывода / ошибки, сервер ssh не будет читать индикацию EOF в этих дескрипторах и не будет закрывать сеанс.

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

ssh mike@127.0.0.1 '/home/mike/test.sh > /dev/null 2>&1'
(note the quotes are important)

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

В качестве альтернативы, вы можете добавить перенаправление в скрипт:

#!/bin/bash

(
exec > /dev/null 2>&1
sleep 2 
echo "done"
) &

Это приводит к тому, что дочерний процесс скрипта закрывает свои копии исходного стандартного вывода и стандартной ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...