Зачекати використання команди в 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.