简体   繁体   中英

Linux Shell Scripting: if/else works on bash but not zsh or sh

Here's an installer I'm writing with all the irrelevant bits removed:

#!/bin/bash

echo "In the prompt below, type 'install' or 'remove' (without the quotes)"
echo "If you type neither, this script will terminate."
read -p "Action to perform: " OPERATION

if [ "$OPERATION" == "install" ]
then
  echo "Installing..."
  echo "Install successful!"
elif [ "$OPERATION" == "remove" ]
then
  echo "Removing..."
  echo "Remove successful!"
else
  echo "Aborting with no actions"
fi

This script works exactly as you'd expect. When I type install , the install section executes, when I type remove the remove section executes and finally when I type random characters, it aborts.

But the same script with the #!/bin/bash replaced with either #!/bin/sh or left empty (my regular shell is ZSH), it errors out:

In the prompt below, type 'install' or 'remove' (without the quotes)
If you type neither, this script will terminate.
Action to perform: sdfsdfdsf
./test.sh: 7: [: sdfsdfdsf: unexpected operator
./test.sh: 11: [: sdfsdfdsf: unexpected operator
Aborting with no actions

For some context, I'm on Ubuntu Studio 18.04 with zsh --version printing zsh 5.4.2 (x86_64-ubuntu-linux-gnu) .

Can someone help me understand why this is happening?

On ubuntu 18.04, /bin/sh is symlink to /bin/dash whose [ ... ] does not support == . You can use [ = ] which also works for zsh.

[STEP 101] # grep 18.04 /etc/os-release
VERSION="18.04.2 LTS (Bionic Beaver)"
PRETTY_NAME="Ubuntu 18.04.2 LTS"
VERSION_ID="18.04"
[STEP 102] # ls -l /bin/sh
lrwxrwxrwx 1 root root 4 2019-02-14 09:49 /bin/sh -> dash
[STEP 103] # /bin/sh
# [ a == b ]
/bin/sh: 1: [: a: unexpected operator
# test a == b
/bin/sh: 2: test: a: unexpected operator
# [ a = b ]
# test a = b
# exit
[STEP 104] #

Note that POSIX only mentions "=" and according to dash manual , " Only features designated by POSIX, plus a few Berkeley extensions, are being incorporated into this shell. "

Fist you should update your shebang to use sh instead of bash and then you will have to use a slightly different syntax. You can use shellcheck for detailed errors.

There are a tone of articles describing the difference like: https://stackoverflow.com/a/5725402/3872881

#!/bin/sh

echo "In the prompt below, type 'install' or 'remove' (without the quotes)"
echo "If you type neither, this script will terminate."
echo -n "Action to perform: "
read -r OPERATION

if [ "$OPERATION" = "install" ]
then
  echo "Installing..."
  echo "Install successful!"
elif [ "$OPERATION" = "remove" ]
then
  echo "Removing..."
  echo "Remove successful!"
else
  echo "Aborting with no actions"
fi

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM