process substitution in bash

.!.

The internets are slow tonight, and I'm tired, so I'll just leave you with something quick. Tommorrow I'll pick back up on the podcast script.

Let's look at this short script:


#!/bin/bash
LIST=""
ls | while read FILE ; do
   LIST="${FILE} ${LIST}"
done
echo $LIST

You may be suprised to find that LIST is empty after all that looping. This problem always mystified me until I learned about subshells. The pipe creates another shell, a subshell, where the loop executes. When the pipe ends, so does the subshell and all of it's variables.

Fortunately there is a simple way around this. We need to execute the loop in the current shell, and redirect the command back into the loop from a subshell.


#!/bin/bash
LIST=""
while read FILE ; do
   LIST="${FILE} ${LIST}"
done < <(ls)
echo $LIST

<(ls) creates an un-named pipe from the subshell into this shell. We can now redirect that pipe into the loop with another <.

If that got too confusing, try reading the Process Substitution chapter in the Advanced Bash-Scripting Guide.

Leave a Reply

Your email address will not be published. Required fields are marked *