Tunggu penggunaan perintah di 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

Saya mengharapkan successstatus keluar ketika saya mengirim 0, tetapi saya masih mendapatkan failure.

Juga, waitjangan menunggu selama 300 detik. Sebagai gantinya, saya langsung menerima pesannya. Saya berasumsi $!adalah anak langsung dari $$skrip saya. Bukan?

Apakah mungkin untuk mengambil status keluar dari wait like exit_status=$(wait $!)?

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

Jawaban:

20

Masalahnya adalah Anda mengeluarkan waitsubkulit:

if `wait $!`;then

Karena waitbuiltin, bukan perintah, itu beroperasi pada subkulit , bukan shell Anda saat ini.

Output yang akan Anda lihat tetapi tidak adalah:

wait: pid 12344 is not a child of this shell

... dengan status pengembalian 1.

Untuk melakukan tes, Anda harus melakukannya tanpa menggunakan subkulit.

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

wait $b && echo success || echo failure

Ini memberikan hasil yang Anda harapkan, dan menunggu selama yang Anda harapkan:

$ 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

Anda dapat memeriksa status keluar dari perintah apa pun dengan $?:

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

Ada beberapa kesalahan lain dalam skrip Anda. #!Baris Anda salah, yang saya perbaiki. Anda menetapkan $!untuk $b, tetapi jangan gunakan $b.

bahamat
sumber
12

Hapus backticks.

Seperti, Anda mengeksekusi waitdalam subkulit, yang tidak memiliki akses ke pekerjaan shell induk, sehingga akan segera gagal.


Jika Anda ingin status keluar, dapatkan nilai $?segera setelah menunggu.

command_here &
wait
status=$?
Patrick
sumber
2

Menghapus backticks akan membuat program bekerja, tetapi tidak sepenuhnya karena alasan yang sudah diidentifikasi. Memang benar bahwa waitgagal segera karena berjalan dalam subkulit dan tidak dapat mengakses proses induknya, tetapi program tidak akan berjalan seperti yang diharapkan bahkan jika Anda menggunakan perintah yang berhasil.

The ifpernyataan menjalankan program dan memeriksa apakah status keluar adalah nol atau non-nol. Saat Anda menggunakan backticks, pernyataan if akan mengambil output dari proses, cobalah menjalankannya sebagai program, dan kemudian gunakan kode keluar untuk proses itu. Jadi programnya tidak gagal karenawait gagal, tetapi gagal karena waittidak menghasilkan output apa pun.

Anda dapat membuat skrip berfungsi dengan menggunakan echodi dalam backticks:

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

Atau cukup hapus backticks; lebih mudah untuk semua orang.

Joni
sumber