15

I've the following shell script:

cat <(echo foo)
source <(echo bar=bar)
echo $bar

However it works differently in GNU bash 3.2 and 4.3 as shown below:

$ /bin/bash foo.sh 
foo

3.2.53(1)-release

$ /usr/local/bin/bash foo.sh 
foo
bar
4.3.33(1)-release

Why this works only on one version? Is it a bug or added feature?

It seems the process substitution works fine, however problem lay when sourcing the file.

If this is expected behaviour, what other syntax should I use instead to source something from the standard input to be compatible between different bash versions?

kenorb
  • 155,785
  • 88
  • 678
  • 743
  • Duplicate of http://stackoverflow.com/questions/10520605/bashs-source-command-not-working-with-a-file-curld-from-internet/10527064#10527064 ? – Charles Duffy Sep 15 '15 at 22:17

1 Answers1

19

This is a known limitation in bash 3.2. To work around it:

source /dev/stdin <<<"$(echo bar=bar)"

...or, similarly:

source /dev/stdin <<<"$(cat <(...))"
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 1
    `eval` behavior is not quite identical; look at top-level `return` semantics, for example, or the various arrays used to stack-trace reporting. – Charles Duffy Jun 04 '19 at 12:17
  • Amazing! This also works with `curl`: `source /dev/stdin <<<"$( curl $url )"` – wisbucky Aug 30 '19 at 23:56
  • This limitation still exists in GNU bash 4.4.19(1). – Chad Skeeters Apr 23 '20 at 22:14
  • @ChadSkeeters, I don't believe that's true. Sure you aren't on a platform, like msys2 Windows builds, with broken process substitutions? See it working fine with bash 5 at https://ideone.com/amkRVh; if I could link to an online 4.x sandbox I'd do so as well, but the one I know offhand is only IRC vs web-based. – Charles Duffy Apr 24 '20 at 04:16
  • @CharlesDuffy I'm on MacOS 10.15.4 with bash 4.4.19(1) from brew. Process substitution did not work for me. – Chad Skeeters Apr 28 '20 at 20:44
  • @ChadSkeeters, I don't use/trust/condone Homebrew (making `/usr/local` contents user-writable strikes me as a horrifically bad idea), but I can't reproduce that. Connect to irc.freenode.org, join the channel `#evalbot`, and run `43# source <(echo bar=bar); echo "$bar"` to test in bash 4.3.46(1), or `44# source <(echo bar=bar); echo "$bar"` to test in bash 4.4.46(1). Both work fine, emitting `bar` instead of the empty string. – Charles Duffy Apr 28 '20 at 20:59
  • 1
    @ChadSkeeters, ...I *suspect* that even though you installed bash 4.4 in Homebrew, that your interactive shell is still Apple's 3.2.57(1). Be sure you're running `echo "$BASH_VERSION"` to check your active version, not `bash --version`. – Charles Duffy Apr 28 '20 at 21:00
  • @CharlesDuffy Good catch. My system's bash shell is 3.2.57(1)-release even though I have a newer version installed via brew. My mistake. – Chad Skeeters Apr 29 '20 at 21:43