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

I was expecting success as exit status when I send 0, but I am still getting failure.

Also, wait doesn't wait for 300 seconds. Instead, I get the message immediately. I assume $! is the immediate child of $$ in my script. Isn't it?

Is it possible to capture the exit status of wait like exit_status=$(wait $!)?

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

The problem is that you're issuing wait in a subshell:

if `wait $!`;then

Because wait is a builtin, not a command, it's operating on the subshell, not your current shell.

The output that you would see but aren't is:

wait: pid 12344 is not a child of this shell

...with a return status of 1.

To perform your test you will need to do it without using a subshell.

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

wait $b && echo success || echo failure

This gives the result you expect, and waits as long as you expect:

$ 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

You can check the exit status of any command with $?:

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

There were a couple of other errors in your script. Your #! line was malformed, which I fixed. You assign $! to $b, but don't use $b.

12

Remove the backticks.

As is, you're executing wait in a subshell, which doesn't have access to the parent shell's jobs, so it will immediately fail.


If you want the exit status, get the value of $? immediately after the wait.

command_here &
wait
status=$?
2

Removing the backticks will make the program work, but not entirely because of the reasons already identified. It is true that wait fails immediately because it runs in a subshell and cannot access its parent's processes, but the program would not run as expected even if you used a command that did work.

The if statement runs a program and checks if its exit status is zero or non-zero. When you use backticks, the if statement will take the output of the process, try to run it as a program, and then use the exit code for that process. So the program isn't failing because wait fails, but rather it fails because wait does not produce any output.

You can make the script work by using echo inside the backticks:

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

Or just remove the backticks; easier for everyone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.