The sh
language is not the C
language, you can't just expect one thing that works in one language will work in another language.
sh
is before all a command line interpreter. Most things are done by commands which the shell is there to invoke.
For instance, to evaluate conditional tests, there's a dedicated command for that: [
aka test
. The if
/then
/fi
is a syntax structure of sh
, but its action is based on the success or failure of the command list that is in-between if
and then
.
For the contents of a variable to be passed to a command, you need the $var
syntax. echo foo
passes foo
to the echo
command, echo "$foo"
passes the contents of the $foo
variable to echo
(note the quotes which are important (even critical in the case of the [
command) in sh
to work around an unfortunate misfeature).
In sh
, (...)
is to run a subshell, for the code within to be interpreted in a separate environment (in most sh
implementations, in a child process), and my_env=="dev"
is just the same as my_env="=dev"
¹ which assigns =dev
to the $my_env
variable, which it will succeed to do, so the subshell will also be successful, so the then
part will be run.
The correct syntax would be:
#!/bin/sh -
my_env="$1"
if [ "$my_env" = dev ]; then
MY_TYPE="dev type"
elif [ "$my_env" = stg ]; then
MY_TYPE="stg type"
elif [ "$my_env" = prod ]; then
MY_TYPE="prod type"
fi
printf '%s\n' "$MY_TYPE"
Though here, you'd rather use a case
construct (similar to C
's switch
):
#! /bin/sh -
my_env=${1?Missing type argument}
case $my_env in
(dev | stg | prod)
MY_TYPE="$my_env type"
;;
(*)
printf >&2 '%s\n' "Unsupported type: $my_env"
exit 1
esac
printf 'MY_TYPE = %s\n' "$MY_TYPE"
See also the catch-all that exits with a failure exit status if $my_env
is not among an allowed set to avoid $MY_TYPE
be used uninitialised below, and the ${1?error}
as a quick way to ensure the script is passed at least one argument and report an error to the user if not.
¹ or my_env='=dev'
or my_env==dev
or my_env='='"d"e\v
, but not my_env'==dev'
nor $my_dev==dev
, the important part being that the first =
be literal and unquoted and what's left of it be literal, unquoted and a valid variable name for it to be taken as a variable assignment command. my_env'==dev'
would try and run a command called my_env==dev
(and likely fail to find it)
$shell ./my_script.sh stg
which bit is the command you're actually running? – Chris Davies Mar 07 '22 at 08:29