Jak mogę anulować resztę listy poleceń w Bash?

10

W Bash od czasu do czasu wpisuję listę poleceń i uderzam Enter, a dopiero później zdaję sobie sprawę, że istnieje błąd z niektórymi poleceniami na końcu listy. Wiem, że jeśli naciśniesz Ctrl+ C, zakończy to aktualnie działające polecenie i anuluje resztę listy. Czy jest jakiś sposób, aby anulować resztę listy bez kończenia aktualnie uruchomionego polecenia?

Załóżmy na przykład, że wpisałem coś takiego

foo; bar

lub

foo && bar

gdzie foojest długo działające polecenie, że bardzo ważne jest, aby nie przerywać, i barrobi coś nieodwracalnego i niepożądanego (powiedzmy shutdown -h nowlub rm -rf /). Podczas gdy foonadal działa, czy istnieje ogólny sposób na powiedzenie powłoce, aby fooskończyła, ale nie uruchamiała barpóźniej? (Tak, mogę zmienić uprawnienia bartak, że nie jest wykonywalny, ale nie jest to szczególnie wygodne, jeśli barjest coś takiego rm, że chcę użyć w międzyczasie, nie będzie działać, jeśli nie własny barlub jeśli barjest wbudowana).

Psychonauta
źródło
Możesz zmienić ostatnie barpolecenie na some_command: ^bar^some_commandprzed wykonaniem.
GAD3R
3
@ GAD3R: ale to nie zmodyfikuje bieżącej linii, rozpocznie nową.
Arkadiusz Drabczyk

Odpowiedzi:

3

Zauważyłem, że użycie programu CtrlZdo przejścia do procesu w tle rozwiązuje problem.

foo && bar

Dzięki @Arkadiusz Drabczyk za wskazanie go w komentarzach, które foo; barnie dają kontroli w wymagany sposób.

Następnie:

^Z

[1]+  Stopped                 foo

Polecenie zatrzymuje tylko pierwsze zadanie i

fg %1

Sprowadza to tylko zadanie foona pierwszy plan i kończy zadanie i kończy pracę.

PS: Można to sprawdzić za pomocą dwóch skryptów zapisujących do pliku. Pierwszy śpi przez kilka sekund, aby dać czas na powrót.

Jestem zagubiony, dlaczego CtrlZobsługuje tylko to polecenie i pozostawia resztę. Chciałbym się dowiedzieć.

Revanth Chetluru
źródło
1
Nie mogę tego odtworzyć. Jakiej bashwersji używasz? Używam GNU bash, version 4.3.46(1)-release (x86_64-slackware-linux-gnu). Napisałem 2 skrypty bash, które zapisują różne pliki write1.sh:: pastebin.com/rbKmdWgB i write2.sh: pastebin.com/bNx3VRws . Prowadzę je tak: ./write1.sh ; ./write2.sh. Pierwszy skrypt powtarza wrote 1się kilka razy, naciskam C-z, mówi [1]+ Stopped ./write1.shi od razu widzę wynik drugiego skryptu: wrote 2powtarzany wielokrotnie.
Arkadiusz Drabczyk
2
Myślę, że powodem, dla którego ta metoda działa z command1 && command2rurociągami, jest Control-zwysyłanie SIGCHLDsygnału do procesu. Można to sprawdzić za pomocą echo $?. Bashnastępnie widzi, że pierwszy proces nie zakończył się pomyślnie i nie wykonuje kolejnych procesów.
Arkadiusz Drabczyk
Używam GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16). Tak, myślę, że masz rację. foo; barnie można kontrolować w pożądany sposób. Ale możemy wykonać wymagane zatrzymanie drugiego procesu, Ctrl+Zjeśli polecenie jest uruchomione foo && bar. Zaktualizuję odpowiedź. Dziękujemy za zwrócenie na to uwagi.
Revanth Chetluru,
@ArkadiuszDrabczyk nie Ctrl-Z nie wysyła SIGTSTP?
muru
@RevanthChetluru zauważa, że barwciąż jest zawieszony i pojawia się w wynikach jobs, więc prawdopodobnie również powinien zostać zabity.
mur