I launch a command in background in my bash script. I need to recover the stderr of it in a var and don't know how. Help! :D
#!/bin/bash
existingdestiny="8.8.8.8" #this is google dns for the example
ping -c 1 $existingdestiny -W 1 > /dev/null 2>&1
exitvar=$?
echo "exitvar: $exitvar"
nonexistingdestiny="172.16.0.234" #this is a non accesible ip example
ping -c 1 $nonexistingdestiny -W 1 > /dev/null 2>&1
exitvar=$?
echo "exitvar: $exitvar"
This works, it returns 0 and then 1, which is correct, nice! but if I put the command in background i can't take the stdout. Let's see:
#!/bin/bash
existingdestiny="8.8.8.8" #this is google dns for the example
ping -c 1 $existingdestiny -W 1 > /dev/null 2>&1 &
exitvar=$?
echo "exitvar: $exitvar"
nonexistingdestiny="172.16.0.234" #this is a non accesible ip example
ping -c 1 $nonexistingdestiny -W 1 > /dev/null 2>&1 &
exitvar=$?
echo "exitvar: $exitvar"
It returns 0 and 0 which is not correct. How can I get the correct responses?
The exit code and the standard error output (also known as "stderr") are two different things. The standard error output is an output stream to which any program can write whatever it wants. The exit code (also known as exit status) is an integer returned by the process.
From the snippet in the question, I assume you want to get the exit code.
The special shell symbol $? will indeed return the exit code of the last started command. However, this does not work with commands started in the background via &. This is because since the command is started in the background, it has not finished yet. And even if it had finished, the shell wouldn't know.
In order to get the exit code of a command started in the background via &, you must use the wait command. The exit code of the wait command will then be exactly the exit code of the command that was waited for. The wait command will wait for the background process to finish. If the background process has already terminated, the wait command returns instantly.
In order to use the wait command, you need to know the process ID of the background process. You can get the process ID of a command started in the background with the $! special symbol. Thus, the following code will do what you want:
COMMAND &
pid="$!"
# Optional: Do something else while ping runs
wait "$pid"
exitcode="$?"
echo "exitcode=$exitcode"
Note however that the ping command itself will not stop, so just starting ping in the background and waiting for it will just hang.
I recommend to not run ping in the background. You already use the options -c and -W correctly to make sure ping will not hang.