Bash – Running a bash script from a zsh shell

bashzsh

I'm having problems running a bash script on zsh. The script is similar to the one below and is supposed to run under bash:

#!/bin/bash
echo "<235234>"  | egrep -oe [0-9]+

However, my shell is by default on zsh, so to run the above script what I do is type /bin/bash on my zsh prompt, and then I run . script.sh.

However, this results in an error, and I get:

zsh: no matches found: [0-9]+

(I should get 235234 instead).

At this point I am confused and have the following questions:

  1. If I am in bash, why do I get an error reported by zsh?
  2. Why does the egrep regexp fail? The regular expression looks correct to me.

Note: In case it matters, I am not supposed to modify the script (the script is shared by multiple users and we are not supposed to make changes to it).

Thanks

Best Answer

If the script properly begins with #!/bin/bash (you can't have another comment before that), you should simply execute it by typing /path/to/script.sh, without that . at the beginning. The . is an include statement, it means “execute the contents of this file as if it had been typed here on the command line” (this is called “sourcing” in unix shell jargon).

Running bash and sourcing the script should work. I'm guessing that because you had bash automatically started in some circumstances, but you prefer zsh, you've set up bash to automatically switch over to zsh — maybe with exec zsh in your ~/.bashrc. Don't do that: instead you should switch over to zsh in the file that's executed when you log in, i.e. ~/.profile, and leave .bashrc alone. To have zsh be executed in terminals, set the SHELL environment variable:

# in ~/.profile
export SHELL=/bin/zsh
if [ -t 1 ]; then exec $SHELL; fi

It's unfortunate that you can't modify the script, because it's buggy. The brackets should be quoted, even in bash. If there is a file called 3+ in the current directory, the call to egrep will search for one or more occurrences of the digit 3 instead of a sequence of arbitrary digits. If there is a file called 3+ and a file called 4+, the call to egrep will search for 3s in the file 4+. Here, the difference between bash and zsh only comes into play when no file matches the supplied pattern: bash silently runs the command with the unsubstituted pattern, whereas zsh signals an error (by default).