我想用类似的东西
if [[ ! -z "$ENV" && $ENV == 'production' ]]; then echo "production"; else echo "dev"; fi
但在 BusyBox 中它不起作用:(
sh: 1: [[: not found
看起来任何组合 AND 或 OR 在进入 busybox 的 IF 语句中都不起作用
答案1
[[...]]
是一种 Korn shell 构造,也受bash
和支持,zsh
但不是标准sh
构造(并且不受任何其他 shell 支持)。
busybox
sh
基于ash
它实现了 POSIX 规范的一个子集sh
(在 POSIX 语言环境中,它在很大程度上兼容),并且具有很少的扩展,特别是,不是这个。
2019年编辑。现在,当使用和[[...]]
构建时,busybox ash 也支持ksh 的有限子集以及.ASH_TEST
ASH_BASH_COMPAT
yash
无论如何,在编写sh
脚本时,您应该遵守 POSIXsh
规范。使用的脚本[[...]]
应该调用ksh
,bash
或zsh
显式调用。bash
也是一个主要与 POSIX sh 兼容的 shell,但具有更多扩展(包括这个)。
测试X非空,然后等于就production
没有意义了。如果X== production
,那么显然它不为空。
使用 POSIX shell 和实用程序进行字符串比较,您有几个选项,在这种情况下最明显的是:
该
[
实用程序又名test
,通常内置在 shell 中:if [ "$var" = production ]; then echo PROD fi
构造
case
:case $var in production) echo PROD;; "") echo EMPTY;; *) echo non-PROD;; esac
现在,您可能想检查变量是否是放(与非空相反),在取消引用它之前,在启用该nounset
选项的情况下(使用set -u
orset -o nounset
或 with#! /bin/sh -u
作为 she-bang 行),否则如果未设置a[ "$ENV" = production ]
将导致 shell 退出。$ENV
为此,您需要这样做:
if [ "${var+set}" = set ] && [ "$var" = production ]; then
echo PROD
fi
(您应该避免使用-a
[
AND 运算符,因为它已被弃用且不可靠)。
虽然更好、更规范的方法是:
if [ "${var-}" = production ]; then
echo PROD
fi
nounset
不触发${var+string}
或${var-string}
扩展。如果设置了变量,则${var-}
扩展为内容,否则扩展为空字符串。$var
其他一些注意事项:
$ENV
是一个特殊变量sh
。当以交互方式启动时,它被视为从中读取初始化的文件的路径(相当于~/.bashrc
for bash
)。您不应该将其用于其他目的。
您会发现一些旧的 Unix shell 脚本文献建议使用[ "x$var" = xproduction ]
或[ production = "$var" ]
进行字符串比较。这是为了克服[
aka实用程序的一些旧版本中的错误,这些错误被诸如,或 的test
某些值混淆。现代系统不需要它,但对于非常旧的系统需要记住这一点。无论如何,该构造不存在此类问题。$var
!
(
-n
case
其他可以进行字符串比较的 POSIX 实用程序包括expr
和awk
。
awk_equal() { awk 'BEGIN{exit(!(""ARGV[1] == ""ARGV[2]))}' "$1" "$2"; }
expr_equal() { expr "x $1" = "x $2" > /dev/null; }
if awk_equal "$var" production; then
echo PROD
fi
if expr_equal "$var" production; then
echo PROD
fi
请注意,需要""
在值前面加上 withawk
以确保我们获得字符串比较(否则1
将被视为等于01
or 1e0
),x
出于expr
同样的原因,还要避免值作为expr
运算符出现问题。
对于awk
and expr
(至少 POSIXly),它们并不是真正的平等运算符,而是测试两个操作数是否具有相同的排序顺序,这不一定是同一件事。例如,在我的系统上,expr_equal ② ③
返回 true,因为 ② 和 ③ 都没有定义的排序顺序。一些awk
实现(如gawk
、mawk
和 busybox)awk
会忽略 POSIX 要求,而是进行简单的字节到字节比较。
无论如何,我想不出有什么好的理由让你更喜欢这些[
而不是case
这里。
答案2
您可以使用旧[
语法
if [ -n "$ENV" -a "$ENV" = 'production' ]
(请注意,我使用-n
而不是! -z
因为它读起来更容易,但它是同一件事)。
或者我们可以通过强制字符串具有值来简化为更旧的语法:
if [ "x$ENV" = 'xproduction' ]
最后,-n
测试可能并不真正需要,你可以这样做
if [ "$ENV" = 'production' ]