Можно ли как-то добавить «&& prog2» к уже запущенному prog1?


87

Большинство оболочек предоставляют такие функции, как &&и ;цепочка выполнения команд определенным образом. Но что, если команда уже запущена, могу ли я как-то добавить еще одну команду, которая будет выполняться в зависимости от результата первой?

Скажи я побежал

$ /bin/myprog
some output...

но я очень хотел /bin/myprog && /usr/bin/mycleanup. Я не могу убить myprogи перезапустить все, потому что слишком много времени будет потеряно. Я могу Ctrl+ Zэто и fg/ bgпри необходимости. Позволяет ли это мне соединиться в другой команде?

В основном меня интересует bash, но ответы на все распространенные оболочки приветствуются!

Ответы:


118

Вы должны быть в состоянии сделать это в той же оболочке, в которой вы используете waitкоманду:

$ sleep 30 &
[1] 17440

$ wait 17440 && echo hi

...30 seconds later...
[1]+  Done                    sleep 30
hi

выдержка из страницы руководства Bash

wait [n ...]
     Wait for each specified process and return its termination status. Each n 
     may be a process ID or a job specification; if a job spec is given,  all 
     processes  in that job's pipeline are waited for.  If n is not given, all 
     currently active child processes are waited for, and the return status is 
     zero.  If n specifies a non-existent process or job, the return status is 
     127.  Otherwise, the return status is the exit status of the last process 
     or job waited for.

Ожидание команды должно сделать работу.
BillThor

Существует несколько кратких форм для ввода PID фонового процесса, таких как %, %1и $!. Важно указать PID, иначе всегда будет работать вторая команда.
BillThor

@BillThor - вы просто уточняете ответ или говорите мне это?
Slm

Я уточняю ответ. Равнина waitне сможет обеспечить желаемый результат. Обычно используются короткие формы, так как они менее подвержены опечаткам.
BillThor

2
Позвольте мне первым поздравить вас с новым блестящим значком :)
terdon

63

fgвозвращается с кодом выхода из программы, которую он возобновляет. Поэтому вы можете приостановить вашу программу с помощью, ^Zа затем использовать fg && ...для ее возобновления.

$ /bin/myprog
some output...
^Z
[1]+ Stopped              /bin/myprog
$ fg && /usr/bin/mycleanup

если вы снова приостановите работу до ее завершения и выполните то же самое с другой командой, заменяется ли первоначальная цепочка mycleanup?
Бурхан Али

3
@BurhanAli Приостановка myprogво второй раз приводит fgк завершению с кодом завершения 20, который не равен нулю, поэтому связанная mycleanupкоманда не выполняется.
n.st

1

Не уверен, что то, что вы запрашиваете, возможно, но если у вас все еще есть оболочка, из которой вы запустили программу, вы всегда можете проверить состояние $?завершения последнего процесса:

$ /bin/myprog
some output...
$ if [ $? -ne 0 ];then echo "non-zero exit status";else echo "0 exit status";fi

1
Это будет работать, но он должен будет выполнить это вручную после этого, он хочет запустить это автоматически, когда команда завершится.
SLM

@slm Согласен. У меня нет решения этой проблемы.
Джозеф Р.

3
Проверьте waitкоманду в Bash.
SLM

1

Если задание находится на переднем плане, любая из этих команд будет работать так же, как вы ожидаете.

[ $? -eq 0 ] && prog2
(( $? )) || prog2

ПРИМЕЧАНИЕ: $? будет содержать статус возврата работающей программы при выходе.

Это явно указывает, что будет делать оболочка, если вы изначально ввели команду.

prog1 && prog2

Если первая команда не читает stdinи выполняется на переднем плане, новая команда может быть введена во время выполнения первой команды. Оболочка прочитает и выполнит ее при выполнении первой команды. Если команда будет работать в фоновом режиме, вряд ли она читает stdin.

РЕДАКТИРОВАТЬ: WAITТакже можно использовать задание в фоновом режиме и использовать команду. Это должно быть сделано с осторожностью, если другие задания также выполнялись в фоновом режиме. В спецификации задания требуется, чтобы WAITкоманда возвращала статус ожидаемого задания.


Это будет работать, но он должен будет выполнить это вручную после этого, он хочет запустить это автоматически, когда команда завершится.
SLM

4
@slm Пока команда не читает stdin, новую команду можно вводить во время выполнения первой команды. Оболочка прочитает его, как только будет выполнена первая команда.
BillThor

Если он что-то делает в скорлупе после того, как он был заземлен, скорее всего, он шланг. По крайней мере, согласно предварительному. тестирование я делал до сих пор!
SLM

2
@BillThor Я думаю, вы должны добавить этот комментарий к своему ответу.
Джозеф Р.

2
Да, использование waitтоже не идеально. Преимущество IMO заключается в том, что он дает нам более понятный API, с которым мы имеем дело. Вводить больше команд в командной строке после запуска чего-либо мне показалось немного странным. waitпо-прежнему страдает от отсутствия прямой ссылки на работающий PID, по сравнению с состоянием возврата. Похоже, это проблема больше, поскольку Bash реализует некоторые вещи: stackoverflow.com/questions/356100/… . Так что это может быть так же хорошо, как и получается.
SLM
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.