Mam skrypt bash, który uruchamia skrypt python3 (nazwijmy go startup.sh
), z kluczową linią:
nohup python3 -u <script> &
Kiedy wchodzę ssh
bezpośrednio i wywołuję ten skrypt, skrypt Pythona kontynuuje działanie w tle po zakończeniu pracy. Jednak gdy uruchomię to:
ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> "./startup.sh"
Proces kończy się, gdy tylko go ssh
zakończy i zakończy sesję.
Jaka jest różnica między nimi?
EDYCJA: Skrypt Pythona uruchamia usługę internetową za pośrednictwem Bottle.
EDIT2: Próbowałem również utworzyć skrypt inicjujący, który wywołuje startup.sh
i ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> "sudo service start <servicename>"
działa, ale mam takie samo zachowanie.
EDIT3: Może to coś innego w skrypcie. Oto większość skryptu:
chmod 700 ${key_loc}
echo "INFO: Syncing files."
rsync -azP -e "ssh -i ${key_loc} -o StrictHostKeyChecking=no" ${source_client_loc} ${remote_user}@${remote_hostname}:${destination_client_loc}
echo "INFO: Running startup script."
ssh -i ${key_loc} -o StrictHostKeyChecking=no ${remote_user}@${remote_hostname} "cd ${destination_client_loc}; chmod u+x ${ctl_script}; ./${ctl_script} restart"
EDIT4: Kiedy uruchamiam ostatnią linię ze snem na końcu:
ssh -i ${key_loc} -o StrictHostKeyChecking=no ${remote_user}@${remote_hostname} "cd ${destination_client_loc}; chmod u+x ${ctl_script}; ./${ctl_script} restart; sleep 1"
echo "Finished"
Nigdy nie dociera echo "Finished"
i widzę komunikat serwera butelki, którego nigdy wcześniej nie widziałem:
Bottle vx.x.x server starting up (using WSGIRefServer())...
Listening on <URL>
Hit Ctrl-C to quit.
Widzę „Zakończone”, jeśli ręcznie SSH i sam zabiję proces.
EDIT5: Korzystając z EDIT4, jeśli poproszę o dowolny punkt końcowy, dostanę stronę z powrotem, ale Butelka popełni błąd:
Bottle vx.x.x server starting up (using WSGIRefServer())...
Listening on <URL>
Hit Ctrl-C to quit.
----------------------------------------
Exception happened during processing of request from ('<IP>', 55104)
źródło
strace
jeśli używasz Linuksa lubtruss
Solaris i zobaczysz, jak / dlaczego się kończy. Jak na przykładssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> strace -fo /tmp/debug ./startup.sh
.&
na końcu skryptu uruchamiania? Dodanie&
zabiera zależność twojej sesji ssh od bycia identyfikatorem nadrzędnym (kiedy umierają identyfikatory nadrzędne, to także ich dzieci). Myślę też, że jest to duplikat pytania w oparciu o ten poprzedni post. Post, który przesłałem do ciebie w poprzednim zdaniu, jest duplikatem tego postu, który może zawierać więcej szczegółów.nohup ./startup.sh &
wcześniej, ale miało to to samo zachowanie.startup.sh
zawiera już widelec (nohup python3 -u <script> &
), więc jestem prawie pewien, że nie muszę ponownie rozwidlać.Odpowiedzi:
Odłączę polecenie od jego standardowych przepływów wejścia / wyjścia i błędów:
ssh
potrzebuje wskaźnika, który nie ma już żadnych wyników i że nie wymaga więcej danych wejściowych. Posiadanie czegoś innego jako wejście i przekierowanie środków wyjściowychssh
może bezpiecznie wyjść, ponieważ wejście / wyjście nie pochodzi ani nie dociera do terminala. Oznacza to, że dane wejściowe muszą pochodzić z innego miejsca, a dane wyjściowe (zarówno STDOUT, jak i STDERR) powinny iść gdzie indziej.</dev/null
Część określa/dev/null
jako wejście<script>
. Dlaczego jest to przydatne tutaj:Alternatywnie przekierowanie z innego źródła wejściowego powinno być względnie bezpieczne, o ile bieżąca
ssh
sesja nie musi być otwarta.Z tą
>/dev/null
częścią powłoka przekierowuje standardowe wyjście do / dev / null, zasadniczo je odrzucając.>/path/to/file
będzie również działać.Ostatnia część
2>&1
to przekierowanie STDERR do STDOUT.źródło
nohup python3 -u <script> >/dev/null 2>&1 &
inohup python3 -u <script> > nohup.out 2>&1 &
pracował. Myślałem, że nohup automatycznie przekierowuje wszystkie dane wyjściowe - jaka jest różnica?nohup
posiadasz na zdalnym hoście? POSIXnohup
nie jest wymagany do przekierowaniastdin
, czego mi brakowało, ale powinien nadal przekierowywaćstdout
istderr
.nohup (GNU coreutils) 8.21
.nohup
drukuje jakieś wiadomości, na przykładnohup: ignoring input and appending output to ‘nohup.out’
?Spójrz na
man ssh
:Po uruchomieniu
ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> "./startup.sh"
uruchamiasz skrypt powłoki startup.sh jako polecenie ssh.Z opisu:
Na tej podstawie skrypt powinien być uruchamiany zdalnie.
Różnica między tym a działaniem
nohup python3 -u <script> &
w lokalnym terminalu polega na tym, że działa on jako lokalny proces w tle, podczas gdy komenda ssh próbuje uruchomić go jako zdalny proces w tle.Jeśli zamierzasz uruchomić skrypt lokalnie, nie uruchamiaj startup.sh jako części polecenia ssh. Możesz spróbować czegoś takiego
ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> && "./startup.sh"
Jeśli masz zamiar uruchomić skrypt zdalnie i chcesz, aby ten proces był kontynuowany po zakończeniu sesji ssh, musisz najpierw rozpocząć
screen
sesję na hoście zdalnym. Następnie musisz uruchomić skrypt Pythona na ekranie i będzie on nadal działał po zakończeniu sesji ssh.Patrz ekran Instrukcja użytkownika
Chociaż myślę, że screen jest najlepszą opcją, jeśli musisz użyć nohup, rozważ uruchomienie
shopt -s huponexit
zdalnego hosta przed uruchomieniem polecenia nohup. Alternatywnie możesz użyćdisown -h [jobID]
do zaznaczenia procesu, aby SIGHUP nie został do niego wysłany. 1Zobacz także to podsumowanie, jak
huponexit
działa, gdy powłoka jest opuszczana, zabijana lub upuszczana. Zgaduję, że twój obecny problem jest związany ze sposobem zakończenia sesji powłoki. 2)Na koniec oto kilka przykładów korzystania z shopt huponexit. 3)
źródło
bash
,huponexit
powinno to dotyczyć tylko interaktywnych powłok, a nie skryptów - „Jeśli opcja powłoki huponexit została ustawiona w shopt, bash wysyła SIGHUP do wszystkich zadań, gdy kończy się interaktywna powłoka logowania”.Może warto wypróbować
-n
opcję przy rozpoczynaniussh
? Zapobiegnie to zdalnej zależności procesu od lokalnegostdin
, który oczywiście zamyka się natychmiast possh session
zakończeniu. A to spowoduje zdalne zakończenie cen, ilekroć spróbuje uzyskać do nich dostępstdin
.źródło
Podejrzewam, że masz stan wyścigowy. Poszłoby coś takiego:
Gdyby ssh nie skrócił rzeczy, wydarzyłyby się następujące rzeczy (nie jestem pewien kolejności tych dwóch):
Tak więc ostatnie dwa krytyczne kroki się nie zdarzają, ponieważ startup.sh i ssh kończą się zanim nohup nie zdąży zrobić tego.
Spodziewam się, że Twój problem zniknie, jeśli położysz kilka sekund snu na końcu startup.sh. Nie jestem pewien, ile dokładnie czasu potrzebujesz. Jeśli ważne jest, aby ograniczyć go do minimum, być może możesz spojrzeć na coś w proc, aby zobaczyć, kiedy jest to bezpieczne.
źródło
/proc/$!/comm
czy nienohup
lub bardziej przenośnie użyć danych wyjściowychps -o comm= $!
.To brzmi bardziej jak problem z tym, co robi
python
skrypt lubpython
sam. Jedyne, conohup
tak naprawdę robi (upraszczanie przekierowań), to po prostu ustawienie obsługiHUP
sygnałuSIG_IGN
(ignorowanie) przed uruchomieniem programu. Nic nie stoi na przeszkodzie, aby program przywrócił goSIG_DFL
lub zainstalował własny program obsługi po uruchomieniu.Jedną z rzeczy, które warto wypróbować, jest umieszczenie polecenia w nawiasach, aby uzyskać efekt podwójnego rozwidlenia, a
python
skrypt nie jest już dzieckiem procesu powłoki. Na przykład:Inną rzeczą, która może być również warta wypróbowania (jeśli używasz,
bash
a nie innej powłoki) jest użyciedisown
wbudowanego zamiastnohup
. Jeśli wszystko działa tak, jak zostało to udokumentowane, nie powinno to mieć żadnego znaczenia, ale w interaktywnej powłoce uniemożliwiłoby toHUP
propagację sygnału dopython
skryptu. Możesz dodać disown w następnym wierszu lub tym samym, co poniżej (uwaga, że dodanie;
po a&
jest błędem wbash
):Jeśli powyższe lub niektóre ich kombinacje nie działają, to z pewnością jedynym miejscem na rozwiązanie tego problemu jest
python
sam skrypt.źródło
huponexit
rzeczy, uruchomienie w podpowłoce powinno mieć taki sam efekt, ponieważdisown
proces nie zostanie dodany do listy zadań.disown
. Nie spodziewaj się jednak, że to wiele zmieni. Myślę, że najlepiej jest zmienićpython
skrypt, aby informował cię, dlaczego się kończy.nohup
jego wykonaniem.Myślę, że to dlatego, że praca jest związana z sesją. Gdy to się skończy, wszystkie zadania użytkownika również zostaną zakończone.
źródło
Jeśli
nohup
możesz otworzyć plik wyjściowy, możesz mieć o tym pojęcianohup.out
. Możliwe jest, żepython
nie jest na ścieżce po uruchomieniu skryptu przezssh
.Spróbowałbym utworzyć plik dziennika dla polecenia. Spróbuj użyć:
źródło
ssh
do ręcznego uruchamiania skryptu, więc zakładam, że python3 jest na ścieżce.