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