3

I'm using exec like this:

#!/bin/bash
exec > >(tee /tmp/mylog.log) 2>&1
bash -c 'sleep 12312' &

I want the output of the commands to be in a log file, and then I want to start a long running script, and completely detach it, without doing anything to its output.

But I've noticed that running a script with exec to redirect output to a file makes it continue running with the long-running script. For example, save the above script to a file /tmp/start.sh, run it, ps aux will show that /bin/bash /tmp/start.sh is still running!

If I remove the exec line, however, it's working as expected.

So how do I "detach" exec stdout redirection and have the script die once it's over?

3

The bash process that keeps running is the parent of tee, not the original script. You can see that by adding traces that display the process IDs:

#!/bin/bash
echo original=$$
exec > >(echo substitution=$BASHPID; tee /tmp/mylog.log) 2>&1
bash -c 'echo sleeper=$$; sleep 12312' &

This makes an additional bash process appear, the parent of sleep. To get rid of these bash processes, use exec throughout:

#!/bin/bash
echo original=$$
exec > >(echo substitution=$BASHPID; exec tee /tmp/mylog.log) 2>&1
bash -c 'echo sleeper=$$; exec sleep 12312' &

I tested this answer on bash 4.3. Future versions of bash may become smarter about not tail calls (like ksh).

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.