Why does zsh =() syntax works with user input while <() doesn't

49 views Asked by At

I'm running a command prompting user input from stdin and writing export FOO=bar to export some variables in user shell session via source. A simple Python implementation would be:

# myprog.py
val = input()
print("export FOO='" + val + "'")

And my command:

source <(python myprog.py)

This works in bash but not zsh. For some reason, stdin with <() process substitution breaks in zsh: input is not passed to process and CTRL+C / CTRL+D just prints control character like ^C on my terminal without effect (process is not killed). I have to kill the process some other way.

However =() syntax works with zsh:

source =(python myprog.py)

I understand that <() behave differently between bash and zsh, and zsh-specific =() syntax changes sub-process gets written (pipe vs. temporary file)... But why does stdin breaks so badly with zsh+ <() ? I can't find anything related to zsh's stdin behavior in process substitution.

(For context, the "real" program is novops: it loads environment variables in current user shell via source <(novops load), prompting user via stdin for an environment to use)

EDIT: Easier way to reproduce by simply reading and outputting with plain commands

# works with bash
# not with zsh
cat <(read foo && echo $foo)

# works with zsh
cat =(read foo && echo $foo)

Also possible to reproduce with container: docker run -it zshusers/zsh:5.9

0

There are 0 answers