Mic*_*ant 47 shell posix portability test
我知道我可以
$ [ -w /home/durrantm ] && echo "writable"
writable
Run Code Online (Sandbox Code Playgroud)
或者
$ test -w /home/durrantm && echo "writable"
writable
Run Code Online (Sandbox Code Playgroud)
或者
$ [[ -w /home/durrantm ]] && echo "writable"
writable
Run Code Online (Sandbox Code Playgroud)
我喜欢使用第三种语法。它们在所有方面以及所有负面和边缘情况下都等效吗?可移植性是否有任何差异,例如 Ubuntu 上的 bash 和 OS X 上的 bash 或较旧/较新的 bash 版本,例如 4.0 之前/之后,它们是否都以相同的方式扩展表达式?
ter*_*don 35
是的,存在差异。最便携的是test或[ ]。这些都是POSIXtest规范的一部分。
该if ... fi构造也由 POSIX 定义,并且应该是完全可移植的。
本[[ ]]是一个ksh功能,它也存在于某些版本bash(所有现代的),在zsh也许在别人,但不存在sh或dash或其他各种简单的炮弹。
因此,要使您的脚本可移植,请使用[ ],test或if ... fi.
Cos*_*tas 31
[是test命令的同义词,它同时是bash 内置命令和单独命令。但[[是一个bash 关键字,仅在某些版本中有效。因此,出于便携性的原因,您最好使用单个[]或test
[ -w "/home/durrantm" ] && echo "writable"
Run Code Online (Sandbox Code Playgroud)
rus*_*ush 20
请注意,这[] && cmd与if .. fi构造不同。
有时它的行为非常相似,您可以使用[] && cmd代替if .. fi. 但只是有时。如果您有多个命令来执行 if 条件,或者您需要if .. else .. fi小心并注意逻辑。
几个例子:
[ -z "$VAR" ] && ls file || echo wiiii
Run Code Online (Sandbox Code Playgroud)
不一样
if [ -z $VAR ] ; then
ls file
else
echo wiii
fi
Run Code Online (Sandbox Code Playgroud)
因为 ifls将失败,echo将被执行,而if.
另一个例子:
[ -z "$VAR" ] && ls file && echo wiii
Run Code Online (Sandbox Code Playgroud)
不一样
if [ -z "$VAR" ] ; then
ls file
echo $wiii
fi
Run Code Online (Sandbox Code Playgroud)
虽然这个结构会起到同样的作用
[ -z "$VAR" ] && { ls file ; echo wiii ; }
Run Code Online (Sandbox Code Playgroud)
请注意;echo 很重要并且必须在那里。
所以上面的恢复语句我们可以说
[] && cmd == 如果第一个命令成功则执行下一个命令
if .. fi == if 条件(也可能是测试命令)然后执行命令
因此,仅用于[和[[使用之间的便携性[。
if与 POSIX 兼容。因此,如果您必须在两者之间做出选择[并if选择查看您的任务和预期行为。
IMS*_*SoP 10
它实际上&&是替换if, 而不是test: ifshell 脚本中的语句测试命令是否返回“成功”(零)退出状态;在您的示例中,命令是[.
因此,这里实际上有两件事要改变:用于运行测试的命令,以及用于根据测试结果执行代码的语法。
测试命令:
test是用于评估字符串和文件属性的标准化命令;在您的示例中,您正在运行命令test -w /home/durrantm[是该命令的别名,同样标准化,它有一个强制的最后一个参数,]以便看起来像一个括号表达式;不要被愚弄了,它仍然只是一个命令(你甚至可能会发现你的系统有一个名为 的文件/bin/[)[[是一些 shell 中内置的 test 命令的扩展版本,但不是同一 POSIX 标准的一部分;它包括您在此处未使用的额外选项条件表达式:
&&操作者(这里标准化)进行逻辑与运算,通过评估两个命令并返回0(表示真),如果他们都返回0; 如果第一个命令返回零,它只会评估第二个命令,因此它可以用作简单的条件if ... then ... fi构建体(此处标准化)使用判定“真”的相同的方法,但允许语句的在化合物列表then条款,而不是由一个提供的单个命令&&的短路,并提供elif和else子句是很难写仅使用&&和||。请注意,if语句中的条件周围没有括号。因此,以下都是同样可移植且完全等效的示例效果图:
test -w /home/durrantm && echo "writable"[ -w /home/durrantm ] && echo "writable"if test -w /home/durrantm; then echo "writable"; fiif [ -w /home/durrantm ]; then echo "writable"; fi虽然以下也是等效的,但由于 的非标准性质而不太便携[[:
[[ -w /home/durrantm ]] && echo "writable"if [[ -w /home/durrantm ]]; then echo "writable"; fi如果您想在类似 Bourne 的世界之外具有可移植性,那么:
test -w /home/durrantm && echo writable
Run Code Online (Sandbox Code Playgroud)
是最便携的。它适用于伯恩csh和rc家庭的贝壳。
test -w /home/durrantm && echo "writable"
Run Code Online (Sandbox Code Playgroud)
将输出"writable"而不是writable在系列的 shell 中rc(rc, es, akanga, where "is not special)。
[ -w /home/durrantm ] && echo writable
Run Code Online (Sandbox Code Playgroud)
在没有命令的系统上的csh或rc系列的shell 中不起作用(已知某些具有但没有它的别名)。[$PATHtest[
if [ -w /home/durrantm ]; then echo writabe; fi
Run Code Online (Sandbox Code Playgroud)
仅适用于伯恩家族的贝壳。
[[ -w /home/durrantm ]] && echo writable
Run Code Online (Sandbox Code Playgroud)
仅适用于ksh(起源地)zsh和bash(伯恩家族中的所有 3 个)。
没有一个可以fish在你需要的shell 中工作:
[ -w /home/durrantm ]; and echo writable
Run Code Online (Sandbox Code Playgroud)
或者:
if [ -w /home/durrantm ]; echo writable; end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11051 次 |
| 最近记录: |