I have a simple script involving a for
loop from bash that I am trying to get working in zsh. I had assumed that the shebang would ensure a POSIX compliant shell would be used (on my system I have /bin/sh -> dash*
) so there wouldn't be any issues.
MWE script where ITEMS
is actually the output of a command that lists packages e.g. ITEMS=$(pip freeze)
:
#!/bin/sh
# ITEMS=$(pip freeze) # Example of useful command
ITEMS="Item1
Item2
Item3" # Dummy variable for testing
for ITEM in $ITEMS; do
echo $ITEM
echo Complete
done
This is the output when I try to run the script in zsh
:
$ source scratch.sh
Item1
Item2
Item3
Complete # Undesired
$ . ./scratch.sh
Item1
Item2
Item3
Complete # Undesired
$ bash scratch.sh
Item1
Complete
Item2
Complete
Item3
Complete # Desired
$ sh scratch.sh
Item1
Complete
Item2
Complete
Item3
Complete # Desired
When I run it in a bash terminal it works fine. I think I've misunderstood how the shebang is interpreted by zsh
? Can someone please explain to me how it should be used such that when I run source scratch.sh
or . ./scratch.sh
I have the same output as if I had run sh scratch.sh
? I know I could modify my for loop script to be compliant with zsh
and bash
natively, but I want to use /bin/sh -> dash
so I'm always using a posix compliant shell and don't have to worry about bashisms or zshisms.
Apologies if this is a basic question, I did search for zsh
, posix
and shebang but didn't find a similar question.
/bin/sh
is a symlink to/bin/dash*
. If you want it to run withdash
, then just run it as./scratch.sh
. The shebang is already#!/bin/sh
.echo $ITEM
in your./scratch.sh
is asking for trouble -- eg.ITEM="-n \nq"; echo $ITEM
manages to do something different in dash, bash, zsh and ksh.UNOS
from 1980 introduced user space support for#!
in 1984 in their default shell. All other platforms I am aware of only support#!
in the kernel and that won't help you.