Próbuję napisać bash
skrypt, aby otworzyć niektóre pliki (głównie pliki pdf) za pomocą gnome-open
polecenia. Chcę również, aby terminal zakończył pracę po otwarciu pliku pdf.
Próbowałem dodać exit
na końcu mojego skryptu, ale to nie zamyka terminalu. Próbowałem znaleźć w Internecie odpowiedź na moje pytanie, ale nie mogłem znaleźć żadnej właściwej. Byłbym bardzo wdzięczny, gdybyście mogli pomóc.
Potrzebuję odpowiedzi, która zabija tylko terminal, z którego uruchamiam polecenie, nie wszystkie terminale, czy byłoby to możliwe? Poprzednia odpowiedź, którą zaakceptowałem, zabija wszystkie otwarte okna terminali. Do dzisiaj nie zdawałem sobie sprawy, że tak jest.
command-line
bash
scripts
Rumesh
źródło
źródło
gnome-open
sięxdg-open
w moim skrypcie, ale nie ma zmian. Terminal nadal pozostaje otwartyOdpowiedzi:
Jeśli otwierasz tylko jeden plik, tak naprawdę nie musisz używać skryptu, ponieważ skrypt ma być łatwym sposobem uruchamiania wielu poleceń z rzędu, podczas gdy tutaj wystarczy uruchomić dwa polecenia (w tym
exit
) .Jeśli chcesz uruchomić
exit
po poleceniu lub po łańcuchu poleceń, możesz połączyć go z tym, co już masz, używając&&
operatora (który w przypadku powodzenia poprzedniego polecenia / łańcucha poleceń wykona następne polecenie) lub za pomocą;
operator (który zarówno w przypadku powodzenia, jak i niepowodzenia poprzedniego polecenia / łańcucha poleceń wykona następne polecenie).W tym przypadku byłoby to coś takiego:
* <ścieżka_do_pliku_pfd> = ścieżka do pliku pdf
exit
umieszczony na końcu skryptu nie działa, ponieważ po prostu wychodzi zbash
instancji, w której skrypt jest uruchamiany, czyli innejbash
instancji niż wewnętrznabash
instancja terminala .Jeśli mimo wszystko chcesz użyć skryptu, najprostszym sposobem jest wywołanie skryptu w następujący sposób:
Lub jeśli skrypt znajduje się w bieżącym katalogu roboczym terminala, tak:
Jeśli naprawdę nie chcesz / nie możesz tego zrobić, drugim najprostszym sposobem jest dodanie tej linii na końcu skryptu:
Spowoduje to wysłanie
SIGKILL
sygnału do procesu macierzystego skryptu (bash
instancja połączona z terminalem). Jeśli tylko jednabash
instancja jest powiązana z terminalem, zabicie spowoduje, że terminal sam się zamknie. Jeśli wielebash
wystąpień jest połączonych z terminalem, to zabicie nie spowoduje zamknięcia się terminalu.źródło
SIGTERM
tutaj nie wystarczy.Ten skrypt kończy terminal, a tym samym powłokę i siebie.
Bezlitośnie zabija wszystkie procesy. Jeśli w terminalu jest otwartych wiele kart, są one również zamknięte.
Problem polega na tym, że jeśli otwartych jest kilka terminali, a są to procesy potomne
gnome-terminal-server
, wszystkie terminale zostaną zabite.W takim przypadku skrypt powinien zostać uruchomiony w niezależnym terminalu, np
xterm
PPID
PPID jest identyfikatorem procesu nadrzędnego, w tym przypadku shell (
e.g. /bin/bash
)PPPID
PPPID to identyfikator procesu nadrzędnego PPID, w tym przypadku okno terminala
<your_command> & disown
W powłoce bash wbudowane polecenie disown służy do usuwania zadań z tabeli zadań lub oznaczania zadań, aby sygnał SIGHUP nie był do nich wysyłany, jeśli powłoka nadrzędna je odbierze (np. Jeśli użytkownik się wyloguje).
awk '{print $4}' "/proc/$PPID/stat"
Pobiera wartość czwartej kolumny pliku
/proc/$PPID/stat
(np/proc/1/stat
. Zwraca 0)źródło
ps xa | grep $$
=>4381 pts/0 Ss 0:01 /usr/bin/zsh
Możesz użyć .
exec ./your-script
Emulator terminala, taki jak GNOME Terminal, kończy działanie, gdy początkowy proces w nim działający - zwykle jest to powłoka - kończy działanie.
Jeśli jesteś już w terminalu i jedyną rzeczą, którą chcesz zrobić przed zamknięciem tego terminalu, jest uruchomienie określonego skryptu (lub programu), oznacza to, że nie potrzebujesz już powłoki, która w nim działa. W ten sposób możesz użyć
exec
wbudowanej powłoki, aby powłoka zastąpiła się procesem utworzonym przez twoje polecenie.exec
.Składnia jest np .
exec command
exec ./your-script
exec
: przykładZałóżmy na przykład, że mam skrypt powłoki o nazwie
count
, oznaczony jako wykonywalny i umieszczony w bieżącym katalogu. Zawiera:I w terminalu uruchamiam:
Drukuje cyfry
5
,4
,3
,2
i1
jeden za drugim, a następnie końcowe okno zostanie zamknięte.Jeśli uruchomisz to z czegoś innego niż pierwszy proces uruchamiany w twoim terminalu - na przykład, jeśli
bash
najpierw uruchomiłeś, aby uruchomić inną instancję powłoki - to spowoduje to powrót do powłoki, która utworzyła ten proces, zamiast wychodzenia z terminalu. (To zastrzeżenie dotyczy w równym stopniuexit
metod opartych na bazach danych).Możesz użyć .
./your-script; exit
Jeśli nie chcesz, aby twoja powłoka zastąpiła się nowym procesem (via
exec
), możesz nakazać mu pozostanie, ale opuści się natychmiast po zakończeniu nowego procesu.Aby to zrobić, uruchom polecenie i
exit
polecenie, oddzielając je,;
aby można je było podać w jednym wierszu.Składnia jest
command; exit
np ../your-script; exit
command; exit
vs.command && exit
Możesz zauważyć, że wygląda to podobnie do metody sugerowanej w odpowiedziach kos i heemayl . Różnica polega na tym, że:
./your-script && exit
&&
uruchamia drugie polecenie tylko wtedy, gdy pierwsze polecenie zgłosiło, że powiodło się, zwracając kod wyjścia równy zero.;
uruchamia drugie polecenie niezależnie od tego, czy pierwsze polecenie zgłosiło powodzenie.Który chcesz zależy od konkretnej sytuacji. Jeśli polecenie nie powiedzie się, czy chcesz, aby powłoka wywołująca (i terminal hostujący) pozostała aktywna? Jeśli tak, użyj
&&
; jeśli nie, użyj;
.Istnieje również
command || exit
, który zamyka powłokę wywołującą tylko w przypadkucommand
zgłoszenia awarii .źródło
Możesz pobrać skrypt zamiast go uruchamiać np
źródło
Osobiście wykonałbym polecenie, aby otworzyć pdf lub inne pliki w podpowłoce, opóźnić zezwolenie na otwarcie plików, a następnie wyjść. Zasadniczo oto, co przetestowałem
(nohup gnome-open *.pdf &); sleep 2; exit
Różnica w tym zakresie byłaby
nohup gnome-open *.pdf && sleep 2 && exit
źródło
nohup
ignoruje sygnał rozłączenia,nohup xdg-open some_program
działał dla mnie iexit
był niepotrzebny.nohup
przekierowuje wiadomość donohup.out
pliku:nohup: ignoring input and appending output to nohup.out
Najprostszym rozwiązaniem byłoby:
W przeciwieństwie do innych podobnych poleceń
nohup
nie jest konieczne, aby polecenie zostało zignorowaneSIGHUP
, przyczyną jestxdg-open
zakończenie procesu odradzania procesu potomnego, który jest preferowaną aplikacją do otwierania pliku pdf. Ponieważ faktyczny proces rozpoczęty z terminala nie jest już tam do zabicia,nohup
nie jest potrzebny.&&
wskazuje, że następne polecenie zostanie uruchomione, jeśli poprzednie polecenie zakończy się powodzeniem, tj. zwróci kod wyjścia0
($?=0
) iexit
po prostu zamknie terminal.źródło
exit
na końcu i nie działał ..exit
w skrypcie, co jest nieużyteczne, ponieważ powoduje wyjście zbash
instancji, w której skrypt jest wykonywany, a nie zbash
instancji nadrzędnej (połączonej z terminalem), co spowodowałoby zamknięcie terminaluxdg-open
działa już w tle i jest odłączony od terminala, więc nie potrzebujesznohup
tutaj, a ponadto z tego, co rozumiem, OP uruchamia sięxdg-open
wiele razy w skrypcie, aby otwierać wsadowo wiele plików, użyciexdg-open
tego w skrypcie spowodowałoby skrypt do zjazdu na pierwszymxdg-open
wystąpieniemxdg-open
w tle, nawet jeśli miałemnohup
to z innego powodu i muszę tam być .. każdy proces w tle z terminala źródłowego zostanie zabity, gdy zabijesz terminal nadrzędny ..nohup
jest to, aby zapobiec to ... ponieważ nie muszę ponownie używać terminala interaktywnie, nie ma potrzeby umieszczania procesu w bg.. w drugim punkcie, któremu można również zapobiec, uruchamiając każdyxdg-open && exit
w podpowłoce ..Aby wyraźnie odpowiedzieć na pytanie tytułowe,
„Wyjdź z terminala po uruchomieniu skryptu bash” :
Uruchom tylko skrypt w terminalu
Nie patrząc na szczegóły działania skryptu, skrypt można uruchomić bezpośrednio w terminalu za pomocą opcji
-e
(--command
), bez uruchamiania powłoki - jest on używany zamiast powłoki:Użyj opcji
-x
(--execute
), jeśli chcesz podać argumenty do skryptu. Dzięki temu cała reszta wiersza poleceń jest traktowana jako polecenie i argumenty.Jeśli skrypt zakończy działanie, nie ma interaktywnej powłoki, która mogłaby zatrzymać wszystko, czekając na dane wejściowe użytkownika.
Przykłady
Teminal zakończy działanie po wyjściu z uruchomionego polecenia - w ten sposób zamknie się po
sleep
uruchomieniu 4 sekund, bez powłoki:Oczywiście możesz nadal używać skryptów powłoki, ponieważ twój skrypt i tak używa innej instancji powłoki.
Możesz także uruchomić powłokę z jawnym skryptem - nie będzie interaktywny:
źródło