Чи можу я якось додати "&& prog2" до вже запущеної прог1?


87

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

Скажіть, я побіг

$ /bin/myprog
some output...

але я дуже хотів /bin/myprog && /usr/bin/mycleanup. Я не можу вбити myprogі перезапустити все, тому що буде втрачено занадто багато часу. Я можу Ctrl+ Zта fg/ bgпри необхідності. Це дозволяє мені ланцюжок в іншій команді?

Мене найбільше цікавить баш, але відповіді на всі звичайні оболонки вітаються!

Відповіді:


118

Ви повинні зробити це в тій же оболонці, в якій ви знаходитесь, з waitкомандою:

$ sleep 30 &
[1] 17440

$ wait 17440 && echo hi

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

уривок зі сторінки чоловіка Баша

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.

EDIT: Розміщення завдання у фоновому режимі та використання WAITкоманди також може бути використане. Це потрібно робити обережно, якщо інші завдання також виконувались у фоновому режимі. Необхідна специфікація завдання, щоб WAITкоманда повертала статус очікуваного завдання.


Це спрацює, але йому доведеться запустити це вручну після цього, він хоче запустити це автоматично, коли команда закінчиться.
slm

4
@slm Поки команда не читає stdin, нову команду можна вводити під час виконання першої команди. Оболонка прочитає її, як тільки буде виконана перша команда.
BillThor

Якщо він зробить що-небудь в оболонці після того, як він виявився в фоновому режимі, він, швидше за все, шланг. Принаймні згідно з прелітом. тестування, яке я робив поки що!
slm

2
@BillThor Я думаю, ви повинні додати цей коментар до своєї відповіді.
Джозеф Р.

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