Как я могу отменить остальные команды в Bash?

10

В Bash иногда я набираю список команд и нажимаю Enter, и только позже понимаю, что есть ошибка с какой-то командой в конце списка. Я знаю, что если я нажму Ctrl+, Cэто прервет текущую команду и отменит оставшуюся часть списка. Есть ли способ отменить оставшуюся часть списка без завершения текущей запущенной команды?

Например, допустим, я набрал что-то вроде

foo; bar

или

foo && bar

где fooэто долгосрочная команда, которую очень важно не прерывать, и она barделает что-то необратимое и нежелательное (скажем, shutdown -h nowили rm -rf /). Пока fooвсе еще работает, есть ли общий способ сообщить оболочке, чтобы она fooзаканчивала работу, но не запускалась barвпоследствии? (Да, я мог бы изменить разрешения для barтого, чтобы он не выполнялся, но это не особенно удобно, если я хочу использовать barчто-то вроде rmэтого, и не будет работать, если я не являюсь владельцем barили если barон встроен.)

Psychonaut
источник
Вы можете изменить последнюю barкоманду на some_command: ^bar^some_commandперед выполнением.
GAD3R
3
@ GAD3R: но это не изменит текущую строку, она начнет новую.
Аркадиуш Драбчик,

Ответы:

3

Я заметил, что использование CtrlZдля перевода программы в фоновый режим делает свое дело.

foo && bar

Спасибо @Arkadiusz Drabczyk за то, что он указал на это в комментариях, которые foo; barне дают контроля требуемым образом.

Потом:

^Z

[1]+  Stopped                 foo

Команда останавливает только первую задачу и

fg %1

Это выводит только задачу fooна передний план и завершает задачу и завершает работу.

PS: Это можно проверить с помощью двух скриптов, записывающих в файл. Первый спит несколько секунд, чтобы дать время вернуться.

Я заблудился от того, почему CtrlZобрабатывает только запущенную команду и оставляет все остальное. Хотел бы узнать.

Ревант Четлуру
источник
1
Я не могу воспроизвести это. Какую bashверсию вы используете? Я использую GNU bash, version 4.3.46(1)-release (x86_64-slackware-linux-gnu). Я написал 2 скрипта bash, которые пишут в разные файлы write1.sh:: pastebin.com/rbKmdWgB и write2.sh: pastebin.com/bNx3VRws . Я запускаю их так ./write1.sh ; ./write2.sh. Первый сценарий повторяется wrote 1несколько раз, я нажимаю C-z, он говорит, [1]+ Stopped ./write1.shи я могу сразу увидеть вывод второго сценария: wrote 2повторение неоднократно.
Аркадиуш Драбчик,
2
Я думаю, что причина того, что этот метод работает с command1 && command2конвейерами, состоит в том, что Control-zпосылает SIGCHLDсигнал процессу. Это можно проверить с помощью echo $?. Bashзатем видит, что первый процесс не завершился успешно, и не выполняет следующие процессы.
Аркадиуш Драбчик,
Я использую GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16). Да, я думаю, что ты прав. foo; barне может контролироваться желаемым способом. Но мы можем выполнить необходимую остановку второго процесса с Ctrl+Zпомощью команды run foo && bar. Я обновлю ответ. Спасибо за указание на это.
Ревант Четлуру,
@ArkadiuszDrabczyk не посылает Ctrl-Z SIGTSTP?
Муру
Примечание @RevanthChetluru, barкоторое все еще приостановлено и отображается в jobsвыходных данных, так что, вероятно, его тоже следует уничтожить.
Муру