Yes, exactly. It appears that "source" tries to read from /dev/stdin before anything is ready from the pipe and treats that as an EOF. You do not even need to sleep, you can just use "cat" instead of "echo" to produce the script and "source" fails reliably.
This appears to have been fixed in bash 4.0 (though possibly it was actually fixed in readline 7.0) I now have 2 workarounds that seem to work (at least on the example system where the bug was found): 1) Add sleep to wait for input echo echo '$1' | (sleep 0; . /dev/stdin yes) 2) Use a here-is document . /dev/stdin yes <<'EOF' echo $1 EOF Thanks for your help. On Thu, Jan 10, 2019 at 12:01 AM don fong <df...@dfong.com> wrote: > interesting. it looks like somehow the ". /dev/stdin yes" side isn't > waiting for the "echo echo '$1'" side to write to the pipe. > > in theory, you should be able to delay the echo and it should still work... > > (sleep 1; echo echo '$1') | . /dev/stdin yes > > but on my mac, adding the sleep makes it fail reliably on the first > iteration. > > on my linux machine, it seems to succeed reliably even with the sleep - as > expected. > > > > > > > On Wed, Jan 9, 2019 at 10:54 PM Jeremy <asfbugzi...@nuru.net> wrote: > >> Configuration Information [Automatically generated, do not change]: >> >> Machine: Mac >> >> OS: Darwin >> >> Compiler: gcc >> >> Compilation CFLAGS: Xcode >> >> uname output: Darwin Octo.local 15.6.0 Darwin Kernel Version 15.6.0: Thu >> Jun 21\ >> >> 20:07:40 PDT 2018; root:xnu-3248.73.11~1/RELEASE_X86_64 x86_64 >> >> Machine Type: x86_64-Apple-Darwin >> >> >> Bash Version: 3.2 >> >> Patch Level: 48 >> >> Release Status: relase >> >> >> Although bashbug listed the Patch Level as 48 (and misspelled "release") >> the version string is >> >> 3.2.57(1)-release (x86_64-apple-darwin15) >> >> >> This is on MacOS 10.11.6. If there is a better place for me to report this >> bug, please let me know. >> >> Description: >> >> Sourcing a script from a pipe is not reliable. >> >> >> Repeat-By: >> >> This command line should run forever: >> >> >> i=0; while [ "_$(echo echo '$1' | . /dev/stdin yes)" = "_yes" ]; \ >> >> do echo -n .; ((i++)); done; printf "\n%s\n" $i >> >> >> When I run it, it usually terminates with $i much less than 1,000. >> >