Shell脚本判断环境变量在Ubuntu报错的原因及解决方法
问题描述
我编写了如下Shell脚本:
#! /bin/sh if [ -z "$ENVIRON" ]; then echo "no env set" elif [ "$ENVIRON" == "test" ]; then echo "test mode" else echo "production mode" fi
运行该脚本时出现错误:
[: test: unexpected operator
我尝试将判断语句改为elif [ $ENVIRON == "test" ]; then,但仍出现相同错误。该脚本在Mac系统中运行可得到预期结果:
tw tmp $ cat script.sh #! /bin/sh if [ -z "$ENVIRON" ]; then echo "no env set" elif [ "$ENVIRON" == "test" ]; then echo "test mode" else echo "production mode" fi tw tmp $ ENVIRON=test sh script.sh test mode
但在Ubuntu系统中运行完全相同的脚本时却报错,请问哪里操作有误,该如何解决?
问题原因
核心问题在于字符串比较运算符的兼容性差异:
- Mac系统的
/bin/sh是bash的软链接,bash作为扩展Shell,支持用==做字符串比较 - Ubuntu系统默认的
/bin/sh指向dash,dash是严格遵循POSIX标准的轻量Shell,而POSIX标准规定test命令(即[)仅支持=作为字符串比较运算符,不识别==
解决方法
有两种可靠的解决方案:
方案一:使用POSIX标准的=替换==
修改脚本中的比较运算符,将==换成=,这样脚本可以在所有遵循POSIX标准的Shell环境中正常运行:
#! /bin/sh if [ -z "$ENVIRON" ]; then echo "no env set" elif [ "$ENVIRON" = "test" ]; then echo "test mode" else echo "production mode" fi
方案二:指定用bash执行脚本
如果想继续使用==运算符,可以将脚本的shebang行从#! /bin/sh改为#! /bin/bash,强制使用bash来执行脚本,避开dash的兼容性限制:
#! /bin/bash if [ -z "$ENVIRON" ]; then echo "no env set" elif [ "$ENVIRON" == "test" ]; then echo "test mode" else echo "production mode" fi
内容的提问来源于stack exchange,提问作者Kamrul Khan
相关产品推荐
相关产品推荐

