Чи можу я якось додати "&& 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.