Czy ktoś może szczegółowo wyjaśnić, co robi „set -m”?


17

Na stronie podręcznika jest napisane:

-m Kontrola zadań jest włączona.

Ale co to właściwie oznacza?

Natrafiłem na to polecenie w pytaniu SO , mam ten sam problem co OP, czyli „tkanina nie może uruchomić tomcat”. I set -mrozwiązałem to. OP wyjaśnił trochę, ale nie do końca rozumiem:

Problem polegał na wykonywaniu zadań w tle, ponieważ zostaną one zabite po zakończeniu polecenia.

Rozwiązanie jest proste: wystarczy dodać „set -m;” przedrostek przed poleceniem.

Odpowiedzi:


10

Cytując dokumentację bash (od man bash):

JOB CONTROL
       Job  control  refers to  the  ability  to selectively  stop
       (suspend) the execution of  processes and continue (resume)
       their execution at a later point.  A user typically employs
       this facility via an interactive interface supplied jointly
       by the operating system kernel's terminal driver and bash.

Tak więc, mówiąc najprościej, posiadanie set -m(domyślnie dla interaktywnych powłok) pozwala na użycie wbudowanych funkcji, takich jak fgi bg, które byłyby wyłączone w set +m(domyślnie dla nieinteraktywnych powłok).

Jednak nie jest dla mnie oczywiste, jaki jest związek między kontrolą zadań a zabijaniem procesów w tle przy wyjściu, ale mogę potwierdzić, że istnieje: uruchomienie set -m; (sleep 10 ; touch control-on) &utworzy plik, jeśli wyjdzie z powłoki zaraz po wpisaniu tego polecenia, ale set +m; (sleep 10 ; touch control-off) &nie zrobi tego.

Myślę, że odpowiedź leży w pozostałej części dokumentacji set -m:

-m      Monitor  mode. [...]                     Background pro‐
        cesses run in a separate process group and a  line  con‐
        taining  their exit status is printed upon their comple‐
        tion.

Oznacza to, że zadania uruchomione w tle set +mnie są rzeczywistymi „procesami w tle” („Procesy w tle to te, których identyfikator grupy procesów różni się od terminala”): mają ten sam identyfikator grupy procesów co powłoka, która je uruchomiła, zamiast mieć własne grupa procesów jak właściwe procesy w tle. Wyjaśnia to zachowanie obserwowane, gdy powłoka kończy pracę przed niektórymi zadaniami w tle: jeśli dobrze rozumiem, po wyjściu sygnał jest wysyłany do procesów w tej samej grupie procesów co powłoka (zabijanie zadań w tle rozpoczęło się poniżej set +m), ale nie do tych z innych grup procesów (pozostawiając w ten sposób prawdziwe procesy w tle rozpoczęte pod set -m).

W twoim przypadku startup.shskrypt prawdopodobnie rozpoczyna pracę w tle. Gdy ten skrypt jest uruchamiany w sposób nieinteraktywny, na przykład przez SSH, jak w pytaniu, do którego się łączysz, kontrola zadań jest wyłączona, zadanie „w tle” dzieli grupę procesów zdalnej powłoki, a zatem zostaje zabite, gdy tylko powłoka zostanie zamknięta. I odwrotnie, poprzez włączenie kontroli zadań w tej powłoce, zadanie w tle nabywa własną grupę procesów i nie jest zabijane po wyjściu powłoki macierzystej.


Dziękuję za odpowiedź, ale jak to się ma tomcat/bin/startup.shdo fg/ bg?
laike9m

1
To nie jest bezpośrednio związane; Próbowałem odpowiedzieć „Kontrola zadań jest włączona / co to właściwie oznacza?” w ogólny sposób. Być może nie wyjaśniłem tego, ale twój skrypt wydaje się uruchamiać zadanie w tle, co dotyczy reszty mojej odpowiedzi.
dhag 16.04.15

2

Znalazłem to na liście problemów github i myślę, że to naprawdę odpowiada na twoje pytanie.

To nie jest tak naprawdę problem SSH, to bardziej subtelne zachowanie wokół trybów nieinteraktywnych / interaktywnych BASH i propagacja sygnału do grup procesowych.

Poniższe oparte jest na /programming/14679178/why-does-ssh-wait-for-my-subshells-without-t-and-kill-them-with-t/14866774#14866774 i http: //www.itp.uzh.ch/~dpotter/howto/daemonize , z niektórymi założeniami nie w pełni zweryfikowanymi, ale testy tego, jak to działa, wydają się potwierdzać.

pty / tty = false

Uruchomiona powłoka bash łączy się ze stdout / stderr / stdin rozpoczętego procesu i jest uruchomiona, dopóki nic nie zostanie podłączone do gniazd, a jej dzieci wyszły. Dobry proces deamon zapewni, że nie będzie czekać, aż jego dzieci zakończą działanie, rozwidlają proces potomny, a następnie wychodzą. W tym trybie SSH nie przesyła do SIGNUP żadnego procesu SIGHUP. Wierzę, że zadziała to poprawnie dla większości skryptów wykonujących proces, który sam sobie radzi z deamonizacją i nie musi być w tle. Tam, gdzie skrypty init używają „&” do tła procesu, najprawdopodobniej głównym problemem będzie to, czy proces w tle kiedykolwiek spróbuje odczytać ze standardowego wejścia, ponieważ spowoduje to SIGHUP, jeśli sesja zostanie zakończona.

pty / tty = true *

Jeśli skrypt inicjujący uruchamia proces w tle, nadrzędna powłoka BASH zwróci kod wyjścia do połączenia SSH, który z kolei będzie wyglądał na wyjście natychmiast, ponieważ nie oczekuje na zakończenie procesu potomnego i nie jest blokowane na standardowym wyjściu / stderr / stdin. Spowoduje to, że SIGHUP zostanie wysłany do nadrzędnej grupy procesów powłoki bash, która ponieważ kontrola zadań jest wyłączona w trybie nieinteraktywnym w bash, obejmie właśnie uruchomione procesy potomne. Tam, gdzie proces demona jawnie rozpoczyna nową sesję procesu podczas rozwidlania lub w procesie rozwidlenia, wówczas on lub jego dzieci nie otrzymają PODSUMOWANIA od wychodzącego procesu nadrzędnego BASH. Pamiętaj, że różni się to od zawieszonych zadań, które będą wyświetlać SIGTERM. Podejrzewam, że problemy wokół tego tylko działanie czasami ma związek z niewielkim stanem wyścigowym. http://www.itp.uzh.ch/~dpotter/howto/daemonize , zobaczysz, że w kodzie nowa sesja jest tworzona przez rozwidlony proces, który może nie zostać uruchomiony przed wyjściem z obiektu nadrzędnego, co powoduje losowe sukces / porażka wspomniane powyżej. Instrukcja uśpienia da wystarczająco dużo czasu, aby rozwidlony proces utworzył nową sesję, dlatego w niektórych przypadkach działa.

pty / tty = true, a kontrola zadań jest wyraźnie włączona w bash

SSH nie połączy się z stdout / stderr / stdin powłoki bash ani z żadnym uruchomionym procesem potomnym, co oznacza, że ​​zakończy działanie, gdy nadrzędna powłoka bash zakończy wykonywanie żądanych poleceń. W takim przypadku, przy wyraźnie włączonej kontroli zadań, wszelkie procesy uruchomione przez powłokę bash za pomocą „&” w tle zostaną natychmiast umieszczone w osobnej sesji i nie otrzymają sygnału SIGHUP, gdy proces nadrzędny do sesji BASH wyjdzie ( Połączenie SSH w tym przypadku).

Co jest potrzebne do naprawienia

Myślę, że rozwiązania muszą być wyraźnie wymienione w dokumentacji operacji run / sudo jako szczególny przypadek podczas pracy z procesami / usługami w tle. Zasadniczo albo użyj „pty = false”, albo, gdy nie jest to możliwe, jawnie włącz kontrolę zadań jako pierwszą komendę, a zachowanie będzie prawidłowe.

Od https://github.com/fabric/fabric/issues/395

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.