我是 shell 脚本新手。我编写了一个简单的脚本来有条件地分配变量:
#!/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
echo $MY_TYPE
当我运行它时:
$shell ./my_script.sh dev
它打印出:dev type
,这是正确的。
之后,我再次运行:
$shell ./my_script.sh stg
它还打印出来dev type
。为什么打印不出来stg type
??我的条件逻辑哪里错了?
答案1
语言sh
不是C
语言,你不能指望在一种语言中有效的东西在另一种语言中也能有效。
sh
首先是命令行解释器。大多数事情都是通过 shell 调用的命令来完成的。
例如,要评估条件测试,有一个专用命令:[
又名test
。 //if
是的语法结构,then
但其动作取决于和之间的命令列表的成功或失败。fi
sh
if
then
要将变量的内容传递给命令,您需要语法$var
。echo foo
传递foo
给echo
命令,将变量echo "$foo"
的内容传递$foo
给echo
(注意重要的引号(甚至[
在命令的情况下很关键)来sh
解决一个不幸的错误功能)。
在 中sh
,(...)
是运行一个子 shell,以便在单独的环境中解释其中的代码(在大多数sh
实现中,在子进程中),并且与分配给变量的1my_env=="dev"
相同,它将成功执行此操作,因此子 shell 也会成功,因此该部分将运行。my_env="=dev"
=dev
$my_env
then
正确的语法是:
#!/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"
虽然在这里,您宁愿使用case
构造(类似于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"
$my_env
另请参阅如果不在允许的集合中则以失败退出状态退出的包罗万象,以避免$MY_TYPE
在下面未初始化地使用,并且${1?error}
作为确保脚本至少传递一个参数并向用户报告错误的快速方法如果不。
¹ or my_env='=dev'
or my_env==dev
or my_env='='"d"e\v
,但不是my_env'==dev'
nor $my_dev==dev
,重要的部分是第一个=
是文字且不带引号的,剩下的内容是文字、不带引号的并且是一个有效的变量名称,可将其视为变量赋值命令。my_env'==dev'
会尝试运行一个名为my_env==dev
(并且可能无法找到它)的命令