Chciałbym uruchomić coś takiego:
bash -c "some_program with its arguments"
ale żeby mieć interaktywny bash, działaj po some_program
zakończeniu.
Na pewno -c
nie jest to dobry sposób, jak się man bash
wydaje:
Powłoka interaktywna to taka, która została uruchomiona bez argumentów niebędących opcjami i bez opcji -c
Jak to zrobić?
Główny cel opisano tutaj
UWAGA
- Muszę zakończyć
some_program
Od czasu do czasu - Nie chcę tego umieszczać w tle
- Chcę zostać na
bash
i zrobić coś innego - Chcę móc ponownie uruchomić program
pty.
fg
Odpowiedzi:
Lepiej jest to zrobić ze skryptu Jednak
exec $0.
jeśli jeden z tych deskryptorów plików skieruje się do nieużywanego urządzenia końcowego, to pomoże - musisz pamiętać, że inne procesy też chcą sprawdzić ten terminal.A tak przy okazji, jeśli twoim celem jest, jak zakładam, zachowanie środowiska skryptu po jego wykonaniu, prawdopodobnie lepiej byś był z:
Powłoki
.dot
ibash's source
nie są jednym i tym samym - powłoka.dot
jest POSIX określona jako specjalna powłoka wbudowana i dlatego jest tak blisko zagwarantowania, jak to tylko możliwe, chociaż nie jest to w żaden sposób gwarancją, że będzie tam ...Chociaż powyższe należy zrobić bez problemu. Na przykład możesz:
Powłoka uruchomi skrypt i wróci do interaktywnego monitu - o ile unikasz
exit
powłoki ze skryptu, czyli procesu w tle - i połączy to twoje I / O z/dev/null.
PRÓBNY:
WIELE
JOBS
Moim zdaniem powinieneś trochę lepiej zapoznać się z wbudowanymi opcjami zarządzania zadaniami powłoki. @Kiwy i @jillagre już się na to zwrócili w swoich odpowiedziach, ale może to wymagać dalszych szczegółów. A ja już wspomniano jedną POSIX określony specjalną powłokę wbudowany, ale
set, jobs, fg,
ibg
to niewiele więcej, a jak pokazuje inna odpowiedźtrap
ikill
są dwa jeszcze więcej.Jeśli nie otrzymujesz natychmiastowych powiadomień o stanie równolegle działających procesów w tle, to dlatego, że twoje bieżące opcje powłoki są ustawione na wartość domyślną określoną przez POSIX
-m
, ale możesz je uzyskać asynchronicznie za pomocąset -b
:Bardzo podstawową cechą systemów opartych na Uniksie jest ich sposób obsługi procesu
signals
. Czytałem kiedyś o pouczające artykuł na ten temat, który porównuje ten proces do opisu Douglasa Adamsa z planety NowWhat:Odnosi się to do
kill signals
.Przynajmniej dla mnie powyższy cytat odpowiedział na wiele pytań. Na przykład zawsze uważałem to za bardzo dziwne i wcale nie intuicyjne, że jeśli chcę monitorować
dd
proces, muszę tokill
zrobić. Po przeczytaniu miało to sens.Powiedziałbym, że większość z nich nie próbuje się przystosować bez ważnego powodu - może to być o wiele bardziej irytujące niż byłoby dobrodziejstwem, gdyby kilka procesów spamowało twój terminal wszelkimi informacjami, które ich zdaniem deweloperów mogą być dla Ciebie ważne .
W zależności od konfiguracji terminala (którą możesz sprawdzić
stty -a
) ,CTRL+Z
jest prawdopodobne jest ustawiony na przekazywanieSIGTSTP
do bieżącego lidera grupy procesów pierwszego planu, który jest prawdopodobnie twoją powłoką, i który powinien być również domyślnie skonfigurowany dotrap
tego sygnału i zawiesić twoje ostatnie polecenie. Ponownie, jak pokazują razem odpowiedzi @jillagre i @Kiwy, nic nie stoi na przeszkodzie, aby dostosować tę funkcjonalność do własnych celów, tak jak lubisz.SCREEN JOBS
Aby więc skorzystać z tych funkcji, należy je najpierw zrozumieć i dostosować ich obsługę do własnych potrzeb. Na przykład właśnie znalazłem ten screenrc na Github, który zawiera
screen
powiązania klawiszy dlaSIGTSTP
:Ułatwiłoby to zawieszenie procesu uruchomionego jako
screen
proces potomny lubscreen
sam proces potomny zgodnie z życzeniem.A zaraz potem:
LUB:
Czy planujesz lub planujesz proces tak, jak chcesz.
jobs
Wbudowaną może dostarczyć listę z nich w dowolnym momencie. Dodanie-l
operandu będzie zawierało szczegóły pid.źródło
Oto krótsze rozwiązanie, które spełnia Twoje oczekiwania, ale może nie mieć sensu, chyba że zrozumiesz problem i działanie bash:
Spowoduje to uruchomienie powłoki bash, uruchomienie
some_program
, a posome_program
wyjściu zostaniesz przeniesiony do powłoki bash.Zasadniczo to, co robimy, to podawanie ciosu na STDIN. Ten ciąg jest
some_program with its arguments; exec </dev/tty
. To mówi bashowi, abysome_program
najpierw uruchomił , a następnie uruchomiłexec </dev/tty
. Więc zamiast kontynuować czytanie poleceń z ciągu, który przekazujemy, bash rozpocznie czytanie/dev/tty
.Dzieje się
-i
tak dlatego, że gdy bash się uruchamia, sprawdza, czy STDIN jest tty, a kiedy się uruchamia, nie jest. Ale później będzie, więc zmuszamy go do trybu interaktywnego.Inne rozwiązanie
Innym pomysłem, o którym myślałem, że byłby bardzo przenośny, byłoby dodanie na samym końcu
~/.bashrc
pliku.Następnie, jeśli chcesz najpierw uruchomić powłokę za pomocą polecenia, po prostu wykonaj:
Wyjaśnienie:
Większość z tego powinna być oczywista, ale rezonsem dla rzeczy zmieniających nazwy zmiennych jest to, że możemy zlokalizować zmienną. Ponieważ
$START_COMMAND
jest to wyeksportowana zmienna, zostanie odziedziczona przez dowolne elementy potomne powłoki, a jeśli inna powłoka bash jest jednym z tych elementów potomnych, ponownie uruchomi polecenie. Przypisujemy więc wartość do nowej nieeksportowanej zmiennej ($start_command
) i usuwamy starą.źródło
<<<
nie jest to POSIX, ale możeszecho "string here" | bash -i
zamiast tego. Wtedy nie ma/dev/tty
co jest rzeczą Linux. Ale możesz zduplikować FD przed uruchomieniem basha, a następnie ponownie otworzyć STDIN, który wygląda podobnie do tego, co robisz, ale zdecydowałem się zachować prostotę./dev/tty
to nie Linux, ale zdecydowanie POSIX.To powinno załatwić sprawę:
Edytować:
Oto nowa próba aktualizacji:
Użyj ControlC, zobaczysz to małe menu:
Tak jest w tym przypadku.
Wybierz opcję „bash”
Wybierz opcję „uruchom ponownie”
źródło
CTRL+C
jest tylko efektem ubocznym domyślnej konfiguracji terminala, aby interpretować go jakoSIGINT
. Możesz to zmodyfikować według własnego uznaniastty
.SIGINT
jesttrapped
powyżej z2
.Możesz to zrobić, przekazując skrypt jako plik inicjujący:
Lub możesz przekazać to w wierszu poleceń:
Zauważ, że
--init-file
miał on na celu odczytanie plików inicjujących dla całego systemu,/etc/bash.bashrc
tak abyś mógł chcieć jesource
zapisać w skrypcie.źródło
Naprawdę nie widzę sensu tego robić, ponieważ po uruchomieniu tego programu powróciłeś do powłoki. Możesz jednak do tego:
Spowoduje to uruchomienie interaktywnej bash po uruchomieniu programu.
źródło
Możesz umieścić polecenie w tle, aby utrzymać bieżącą wersję basha otwartą:
Aby powrócić do działania, możesz użyć
fg
polecenia i^+z
ponownie umieścić je w tleźródło
bash
czy nie, używasz dla mnie bardzo obcej powłoki, jeśli nie jest w stanie obsłużyć procesu tła. I zgadzam się z Kiwi - te informacje lepiej by ci służyły, gdyby były w twoim pytaniu.Możesz użyć screena, aby uruchomić polecenie. Następnie możesz ponownie dołączyć do sesji po zakończeniu polecenia.
Alternatywnie, po prostu uruchom polecenie w tle
some_program with its arguments&
. Dzięki temu będziesz mógł ponownie uruchomić polecenie i uzyskać status polecenia po zakończeniu.źródło
screen
ale umieszczenie go w tle nie jest dla mnie przydatne - czasami muszę zakończyć program, zrobić coś innego i uruchomić go ponownie. A głównym celem jest zrobienie tego szybko.kill %
lubkill %1
.