0

I am migrating from bash to zsh. One of the difficulty I met is this script, could anyone help me with this script? I want to use comm command to do a TARGET - PRUNE_FILE operation: remove lines are in both files.proj.bak and prunefile.conf, from files.proj.bak.

TARGET=files.proj.bak
PRUNE_FILE=prunefile.conf

comm -23 <(sort files.proj.bak) <(sort prunefile.conf)

in bash it runs well, but in zsh, I got following error:

/Users/admin/Dropbox/loadrc.home/bashrc/cscope.sh: line 4: syntax error near unexpected token `('
/Users/admin/Dropbox/loadrc.home/bashrc/cscope.sh: line 4: `comm -23 <(sort files.proj.bak) <(sort prunefile.conf)'
4ae1e1
  • 7,228
  • 8
  • 44
  • 77
huangyingw
  • 89
  • 6
  • This is valid syntax in Zsh. But executing the script in Zsh doesn't mean the script is interpreted by Zsh. You need to show us the shebang. `head -1 /Users/admin/Dropbox/loadrc.home/bashrc/cscope.sh`. – 4ae1e1 Nov 12 '19 at 05:46
  • Wait, that's the entirety of the script, without a shebang (seeing that `comm` is line 4)? Then it's executed by POSIX sh. Add `#!/usr/bin/env zsh` to the top of the script. – 4ae1e1 Nov 12 '19 at 05:48
  • By the way here's a related question with some technical details on what happens when a script without shebang is executed: https://stackoverflow.com/questions/7268437/bash-script-execution-with-and-without-shebang-in-linux-and-bsd. Anyway, it's really bad practice so don't do it. – 4ae1e1 Nov 12 '19 at 05:54
  • @4ae1e1 : I agree that the script is obviously not run by Zsh, because if it were, the error message would include _zsh:_. But if it were run by _sh_, the error message would show _sh:_ ... at least it does so in my _sh_. – user1934428 Nov 12 '19 at 08:02
  • @huangyingw : How do you run the script? Do you also receive the error when you source the script? – user1934428 Nov 12 '19 at 08:03
  • "if it were, the error message would include zsh:" "if it were run by sh, the error message would show sh" Both are false. You're obviously on macOS, both statements are demonstrably false, I'm not sure where you got the idea that sh/zsh should appear in the error message. Running `sh /Users/admin/Dropbox/loadrc.home/bashrc/cscope.sh` should produce the exact error messages you posted here. – 4ae1e1 Nov 12 '19 at 10:03
  • Anyway, why does it even matter? You should never execute a script without a shebang as I pointed out above. It's neither well defined nor portable. – 4ae1e1 Nov 12 '19 at 10:03
  • @4ae1e1, thanks for pointing our. Yes, I should add a head like "#!/bin/zsh". Previously its head was "#!/bin/bash", as I want to make it also compatible in zsh, so, I remove that line. – huangyingw Nov 13 '19 at 17:46

1 Answers1

0

Without a shebang, how the script is executed depends on who is executing it.

bash will try to execute it with bash itself, which supports process substitution.

zsh, on the other hand, tries to execute the script using /bin/sh, which (even if it is really bash run under the name sh) does not support process substitution.

The solution is to either run the script with an explicit interpreter that supports whatever syntax appears in the script, for example

$ zsh cscope.sh

or

$ bash cscope.sh

or to add a shebang that specifies an appropriate interpreter, for example #!/bin/bash or #!/bin/zsh.

chepner
  • 497,756
  • 71
  • 530
  • 681