Summary: I have a bash script that runs a process in background, and is supposed to work as a normal command and inside a command substitution block such as $(...)
. The script itself spawns a process that forks to background. It can be reduced to this test case:
#!/bin/sh
echo something
sleep 5 &
Running this script in a shell will return immediately (and print "something"), running it inside $(...)
will hang for 5 seconds, waiting for the backgrounded "sleep" to finish.
Applies to anything that is started inside the command substitution shell and spawns processes in background, including any children in that process tree apparently. Seems to affect both bash and zsh, haven't tried others.
Original question: I have a bash script that is supposed to print a value to stdout and also copy it to the X clipboard every time it runs.
#!/bin/sh
echo something
echo something | xclip -selection clipboard
This script (let's call it "something") is meant to be used to get this word (which is actually the output of another command) and be used in different ways such as:
$ something
something
$ xclip -o -selection clipboard
something
$ echo $(something)
^C
Prints to normal stdout, copies the output to the clipboard to be used in normal X applications, and should also be able to use the stdout with bash command substitution, to insert this word in the middle of any command.
However the bash command substitution seems to force xclip
to stay alive in foreground. xclip
normally daemonizes itself since the X clipboard requires that a client provides the clipboard contents, and the default behavior is to make it quit once the clipboard contents are replaced.
After having this issue with xclip I made the minimal test case that I wrote at the beginning of this question, so it seems to apply that anything that daemonizes inside the $(...)
shell
Can anyone explain this behavior? Is there any way I can avoid it?