Skip to content
Advertisement

Capturing output from a background subshell in bash?

I’m trying to run multiple subshells in a bash script and capture the stdout result to a variable. When I run the subshell in the background I would expect I can use wait to let the subshell complete and then use the variable the result is assigned to later in the program…. but it doesn’t seem to work.

Simple example script:

l=$(ls) &
wait $!
echo "L=$l"

Then when I run it:

$ bash -x test2.sh 
+ wait 16821
++ ls
+ l='test1.sh test2.sh'
+ echo L=
L=

The output from my test program would suggest the variable l should be assigned the result of the subshell, but when I use echo it is empty…

If I don’t background the subshell (or use wait) then it works as expected…

l=$(ls) 
echo "L=$l"

Results in:

$ bash -x test1.sh 
++ ls
+ l='test1.sh test2.sh'
+ echo 'L=test1.sh test2.sh'
L=test1.sh test2.sh

Am I missing something obvious or … ?

Advertisement

Answer

From bash manpage (emphasis mine):

Command substitution, commands grouped with parentheses, and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are re‐set to the values that the shell inherited from its parent at invocation. Builtin commands that are invoked as part of a pipeline are also executed in a subshell environment. Changes made to the subshell environment cannot affect the shell’s execution environment.

So, l=$(ls) & would be like (l=$(ls)) if not backgrounded.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement