Мой сценарий развертывания сервера запускает длительный процесс через SSH, например:
ssh host 'install.sh'
Поскольку мое интернет-соединение дома не самое лучшее, иногда я могу отключиться, пока install.sh
Бег.(Это легко смоделировать, закрыв окно терминала.) Мне бы очень хотелось, чтобы скрипт install.sh
продолжал работать в этих случаях, чтобы я не заканчивал прерванными apt-get
процессами и подобными неприятностями.
Причина, по которой install.sh
убито, заключается в том, что stdout и stderr закрываются, когда сеанс SSH прерывается, поэтому запись в них не удалась.(Кстати, это не проблема SIGHUP - использование nohup не имеет значения.) Если я добавлю touch ~/1 && echo this fails && touch ~/2
в install.sh
, будет создан только ~/1
.
Выполнение ssh host 'install.sh &> install.out'
решает проблему, но затем я теряю любой «живой» прогресс и вывод ошибок.
Поэтому мой вопрос: какой простой / идиоматический способ запустить процесс черезSSH, чтобы он не падал, если SSH умирает, но чтобы я все еще мог видеть вывод при его запуске?
Решения, которые я пробовал:
Когда я запускаю вещи вручную, я использую screen
для подобных случаев, но я не думаю, что это сильно поможет, потому что мне нужно автоматически запускать install.sh
из сценария оболочки.Кажется, что экран сделан для интерактивного использования (он жалуется на «Должен быть подключен к терминалу.»).
Использование install.sh 2>&1 | tee install.out
тоже не помогло (глупо с моей стороны думать об этомmight).
Вы можете перенаправить stdout / stderr в install.out
и затем tail -f
it.Следующий фрагмент на самом деле работает:
touch install.out && # so tail does not bark (race condition)
(install.sh < /dev/null &> install.out &
tail --pid "$!" -F install.out)
Но, конечно, должен быть менее неловкий способ сделать то же самое?