Nie pozwól ekranowi GNU zakończyć sesji po zakończeniu skryptu

35

Próbuję zmusić ekran GNU do utworzenia „wirtualnego” terminala, bez dołączania się do niego, wykonywania skryptu wewnątrz i NIE kończenia sesji po zakończeniu skryptu.

Próbowałem wielu kombinacji, w tym:

screen -dmS udplistener /share/Sys/autorun/start_udp_listeners.sh

lub

screen -S udplistener -X /share/Sys/autorun/start_udp_listeners.sh

i żaden z nich nie działał. Dostaję sesję bez wykonania skryptu, skrypt jest wykonywany, ale sesja zostaje zakończona po zakończeniu lub pojawia się błąd „Nie znaleziono sesji ekranowej”.

W zasadzie staram się uruchomić program nasłuchujący UDP napisany w PHP i sprawić, by działał w nieskończonej pętli (nie przerywaj nasłuchiwania). Tak - na końcu mogłem uruchomić skrypt PHP &, zmuszając CLI PHP do działania jako demon. Problem polega na tym, że używam kawałka śmieci zwanego serwerem (QNAP - nigdy, nigdy nie kupuj tego śmieci!), Co wydaje się ignorować. Skoro tylko wyloguję się z sesji SSH, skrypty przestają działać.

Więc screenwydaje się być jedynym rozwiązaniem. Ale nie rozumiem, dlaczego kończy sesję po zakończeniu wykonania polecenia lub skryptu?

EDYCJA : Próbowałem też znaleźć przykład w Internecie:

screen -dmS name
screen -S name -p windowname -X stuff 'mc
'

Nie brakuje! Po dołączeniu do niego ( screen -R name) widzę, że dowódca północy NIE ZOSTAŁ stracony. Chociaż przykładowy autor powiedział, że tak będzie.

trejder
źródło
Podczas wywoływania screentworzysz tylko jedno okno, aby uruchomić jedno polecenie. Kiedy polecenie kończy się, okno zamyka się i screennie ma już nic do zrobienia, więc wychodzi.
jw013,
Więc ... czy jest sposób, aby otworzyć dwa okna (używając tylko wiersza poleceń, bez kombinacji klawiatury), jedno do wykonania skryptu, a drugie, aby zapobiec screenzamknięciu? BTW: Nadal nie mam pojęcia o tym! Jeśli zadzwonię screen -dmS name, tworzę odłączone okno, które również nie ma już nic do roboty. Ale to nie jest automatycznie zamykane! Ale gdy chcę wykonać coś na tym odłączonym ekranie, kończy się po wykonaniu. Czemu? Nie widzę tu logiki. Czy okno może nic nie robić, ale nie może robić okna, a następnie nic nie robić?
trejder
2
Kiedy uruchamiasz okno bez podania polecenia, nie oznacza to „nic nie robienia”. „Coś”, co robi, to uruchomić interaktywną powłokę, która nie kończy działania, dopóki nie wyjdzie z niej ręcznie.
jw013,
Fajne! Dziękuję za wyjaśnienie! Więc ... wracając do pytania ... czy jest jakiś sposób, aby uruchomić polecenie wewnątrz odłączonego ekranu / okna i NIE zakończyć tej sesji po zakończeniu wykonywania polecenia? Proszę również spojrzeć na zaktualizowane pytanie. Dziękuję Ci.
trejder
Ten skrypt wykonuje dwa detektory UDP napisane w PHP. Mimo że oba są wykonywane jako demony (z &końcem), z powodu błędnego serwera (QNAP), są one przerywane po zakończeniu sesji (powiedziano mi, że nie powinny działać na normalnym Linuksie, jeśli są wykonywane z &). Więc nie zamierzam nic robić po start_udp_listeners.shzakończeniu, tylko jak zapobiec zakończeniu sesji. Dopóki tak nie jest, moi słuchacze PHP działają dobrze.
trejder

Odpowiedzi:

42

Aby ekran był zajęty po zakończeniu skryptu, po prostu utrzymuj coś trwałego w oknie. Najprostszym wyborem dla tego „czegoś” jest prawdopodobnie interaktywna powłoka. Oto jeden ze sposobów, aby to zrobić (zakładając, że bashjest to wybór interaktywnej powłoki):

screen -dmS session_name sh -c '/share/Sys/autorun/start_udp_listeners.sh; exec bash'
  • -dm: uruchamia ekran w trybie odłączonym
  • -S: ustawia nazwę sesji dla ekranu, aby ułatwić późniejsze pobieranie
  • sh -c '...': zamiast po prostu uruchomić skrypt, który się zakończy, użyj sh -cdo uruchomienia wielu poleceń
  • exec bash: po zakończeniu skryptu shpowyższe przełącza się na interaktywną powłokę ( bash), która nigdy nie powinna wyjść, dopóki coś zewnętrznego go nie zakończy. Będzie to screenotwarte, dopóki bashinstancja będzie żywa.
jw013
źródło
1
Hm ... wydaje się, że jesteś wybawcą mojego życia! :] Rozszerzając swoje rozwiązanie, export IGNOREEOF=1aby zapobiec przypadkowemu zakończeniu z Ctrl + D, powinno dać mi idealne rozwiązanie, szukałem cały długi wieczór. DZIĘKI! :]
trejder
Na dzień dzisiejszy to nie działa w Debianie, -c jest argumentem do odczytania alternatywnego pliku .screenrc ...
ToVine
@ToVine działa doskonale na Debian Stable (Wheezy). Użyłem bash -cjednak.
TranslucentCloud,
@TranslucentCloud czy w cudzysłowie umieściłeś całe polecenie „bash -c ...”? Ostatnim razem, gdy spróbowałem (tuż przed napisaniem komentarza), nie działało to dla mnie, nie jestem pewien, dlaczego ...
ToVine
@ToVine tutaj jest moje całe polecenie:screen -LS sauf bash -c "sudo aptitude update && sudo aptitude full-upgrade; exec bash"
TranslucentCloud
2

Nie miałem szczęścia sh -cna moim Raspberry Pi 2 z systemem Debian 7.8. Ale bash -cczy praca:

Dowództwo:

/usr/bin/screen -dmS test-screen bash -c "/usr/bin/top; exec bash"
scotty86
źródło
Czy to możliwe, ponieważ używasz (na Raspberry Pi) innej powłoki? bashI shwydaje się być dwa różne muszle. Myślę, że to wszystko, ale mogę się mylić, ponieważ w ogóle jestem nowicjuszem w Linuksie.
trejder
1
sh jest domyślną powłoką uniksową, jest dołączona do raspbian (debian). Polecenie sh również działa, ale nie sh-c w połączeniu z screenem.
scotty86,
Dziękujemy @ scotty86, obserwowałem to samo w Linux Mint 19 (Ubuntu 18.04) i zmienia sh -csię bash -czałatwiło sprawę. Nie rozumiem dlaczego, oba shi bashsą zainstalowane, więc wciąż nie mogę się nad tym przespać, ale przynajmniej działa.
Redsandro
shprawdopodobnie wskazuje /bin/dashzamiast /bin/bash. Debian zmienił domyślną powłokę z bashna dashkilka lat temu.
scai