Ждать использования команды в Linux?


16
#!/bin/bash
function back()
{
    sleep $1
    exit $2
}
back $1 $2 &
b=$!
if `wait $!`;then
    echo success
else
    echo failure
fi
bash-3.00# ./back 300 0
failure
bash-3.00# ./back 300 1
failure

Я ожидал в successкачестве состояния выхода, когда я отправляю 0, но я все еще получаю failure.

Кроме того, waitне ждет 300 секунд. Вместо этого я получаю сообщение немедленно. Я полагаю, $!это непосредственный ребенок $$в моем сценарии. Не так ли?

Есть ли возможность фиксировать состояние выхода как exit_status=$(wait $!)?

if ! ((exit_status));then
    echo sucess
else
    failure
fi

Ответы:


20

Проблема в том, что вы выпускаете waitв подоболочке:

if `wait $!`;then

Поскольку waitэто встроенная команда, а не команда, она работает на подоболочке , а не на текущей оболочке.

Вывод, который вы видите, но не видите:

wait: pid 12344 is not a child of this shell

... со статусом возврата 1.

Для выполнения теста вам нужно будет сделать это без использования подоболочки.

#!/bin/bash
function back()
{
  sleep $1
  exit $2
}
back $1 $2 &
b=$!

wait $b && echo success || echo failure

Это дает ожидаемый результат и ожидает столько, сколько вы ожидаете:

$ time ./test.sh 3 0
success
./test.sh 3 0  0.00s user 0.01s system 0% cpu 3.012 total
$ time ./test.sh 3 1
failure
./test.sh 3 1  0.00s user 0.01s system 0% cpu 3.012 total

Вы можете проверить состояние выхода любой команды с помощью $?:

$ /bin/true
$ echo $?
0
$ /bin/false
$ echo $?
1

В вашем скрипте было несколько других ошибок. Ваша #!линия была искажена, что я исправил. Вы назначаете $!к $b, но не использовать $b.


12

Убрать галочки.

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


Если вы хотите статус выхода, получите значение $?сразу после ожидания.

command_here &
wait
status=$?

2

Удаление галочек заставит программу работать, но не полностью из-за уже определенных причин. Правда, чтоwait сразу происходит сбой, потому что он работает в подоболочке и не может получить доступ к процессам своего родителя, но программа не будет работать так, как ожидалось, даже если вы использовали команду, которая работала.

ifЗаявление запускает программу и проверяет ее статус выхода равен нулю или отлична от нуля. Когда вы используете обратные пометки, оператор if будет получать выходные данные процесса, пытаться запустить его как программу, а затем использовать код завершения для этого процесса. Таким образом, программа не терпит waitнеудачу, потому что терпит неудачу, а скорее она терпит неудачу, потому чтоwait что не производит никакого вывода

Вы можете заставить скрипт работать, используя echoвнутри обратные ссылки:

if `echo wait $!`; then
    echo success
else
    echo failure
fi

Или просто уберите галочки; проще для всех.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.