Mam skrypt powłoki script.sh
z poleceniem cmd
uruchomionym w tle, to znaczy:
#!/bin/bash
…
cmd &
…
Jeśli otworzę emulator terminala (próbowałem xfce4-terminal i gnome-terminal) i uruchomię się script.sh
w nim, moje polecenie cmd
zostanie skutecznie wykonane i wykonane w tle, zgodnie z oczekiwaniami.
Ale jeśli otworzę emulator terminala z poprzedniej (lub na początku sesji pulpitu, co jest moim prawdziwym przypadkiem użycia) i wykonam skrypt przez
xfce4-terminal -H -x script.sh (or gnome-terminal -x script.sh)
polecenie cmd
nie jest już wykonywane.
Przekonałem się, że mogę zmusić go do wykonania poprzez umieszczenie set -m
w moim skrypcie, ale nie rozumiem, dlaczego jest to konieczne (ani w rzeczywistości wystarczające) w tym przypadku, a nie w poprzednim. Rzeczywiście, jeśli wstawię a set -o
do skryptu, uzyskam taki sam wynik w obu przypadkach.
Czy ktoś może mi to wyjaśnić i / lub powiedzieć właściwy sposób wykonywania zadań w tle w skryptach powłoki? Dzięki!
EDYCJA: W rzeczywistości cmd
jest wykonywana w obu przypadkach, ale w drugim przypadku jest natychmiast zabijana przez zakończenie script.sh
. Aby temu zapobiec, można użyć nohup
, ale to nie wystarczy, i jest to dla mnie najdziwniejsza rzecz: trzeba także postawić sleep 1
coś takiego, aby umożliwić prawidłowe uruchomienie procesu w tle i odłączenie od powłoki nadrzędnej, w przeciwnym razie zostanie zabity.
Naprawdę nie rozumiem tej różnicy w zachowaniu między dwiema powłokami, ponieważ obie nie są interaktywne, jak stwierdzono w poprzednim komentarzu.
cmd
się nie wykonuje? Czy można go łatwo i jednoznacznie znaleźć w wyjściu ps (i trwa wystarczająco długo, aby go znaleźć), czy też wydaje dźwięk lub inne wskazanie GUI?cmd
coś, co można zobaczyć w menedżerze zadań, na przykładsleep n
przyn
wystarczająco dużym rozmiarze . Ale można wybrać coś z GUI, jakfirefox
lub coś innego.Odpowiedzi:
Jeśli otworzysz
xfce4-trminal
lubgnome-terminal
(lub inny terminal) Twoja powłoka jest w trybie interaktywnym. Każdy skrypt jest uruchamiany w trybie interaktywnym.W przypadku uruchomienia
script.sh
przezlub
lub inny terminal, Twoja powłoka jest w trybie nieinteraktywnym.
Skrypty mogą być zmuszane do działania w trybie interaktywnym z
-i
opcją lub z#!/bin/bash -i
nagłówkiem. Należy pamiętać, że może to powodować nieprawidłowe zachowanie skryptu lub wyświetlanie komunikatów o błędach, nawet jeśli nie występuje błąd.Co to jest
set -m
? To tryb monitorowania . Procesy działające w tle działają w osobnej grupie procesów, a po ich zakończeniu drukowany jest wiersz zawierający ich status wyjścia. Jest domyślnie włączony dla interaktywnych powłok.Co to jest
set -o
? Zapisuje bieżące ustawienia opcji na standardowe wyjście w nieokreślonym formacie.Dlaczego
set -o
działaW każdym razie
set -m
jest to preferowany sposób.źródło
set -o
mojego skryptu: w obu przypadkach jego wynik jest taki sam, w szczególności w przypadku trybu monitorowania, który jest wyłączony (domyślnie w trybie nieinteraktywnym). Nieset -o
sprawdzam, czy to działa, ale aby zobaczyć jego wyniki.Odpowiedzi na pytanie udzielił Unix Stackexchange (patrz także dodatkowe komentarze poniżej odpowiedzi). To pytanie, kto wysyła sygnał SIGHUP do kogo i kiedy. I alternatywą dla
set -m / set +m
dookołacmd &
wscript.sh
totrap '' HUP / trap - HUP
.źródło