I have a variable, COMMANDS, that contains a list of newline-separated commands (I know for example in this case that there will never be newlines, but they could be separated by NUL). For example,

echo "foo bar"
tail blah.txt
python3 -c 'print(1 + 10)'

I would like to invoke each of these, but using process substitution feed them all as arguments into another program. Continuing with the example, if I wanted to feed into cat, then I'd expect the following to be run:

cat <(echo "foo bar") <(tail blah.txt) <(python3 -c 'print(1 + 10)')

Is there any way to dynamically do this? The best solution I could come up was to construct this command as a string and give it to bash -c:

bash -c "cat$(echo "$COMMANDS" | while read -r p; do printf ' <(%s)' "$p"; done)"

But this feels a little brittle (and I question its ability to robustly handle input edge cases like quotes).

For anyone wanting to experiment, here's a quick command to setup what I used as my example:

COMMANDS=$(printf 'echo "foo bar"\ntail blah.txt\npython3 -c "print(1 + 10)"')
echo blah > blah.txt
  • 1
    consider an array of commands, so you don't have to worry about newline parsing – Jeff Schaller Aug 30 '18 at 16:40
  • @JeffSchaller I would, but the commands are the output of running another process so newline/NUL parsing must be done at some point. – Bailey Parker Aug 30 '18 at 16:42
  • 2
    readarray -t commands < <(echo 1; echo 2; echo 3) – Jeff Schaller Aug 30 '18 at 16:44
  • @JeffSchaller Oh nice! I've never seen readarray. Will definitely use that more now! :) – Bailey Parker Aug 30 '18 at 16:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.