我读到以下内容Z-Shell 用户指南:
“true”的同义词是“:”;它经常以这种形式使用来给出有副作用但不应该使用的参数 - 类似
: ${param:=value}
这是所有 Bourne shell 衍生物中的常见习惯用法。在参数扩展中,
$param
如果之前为空,则给出 value 值,否则不处理。由于这是参数扩展的唯一原因,因此您通常:
会忽略该参数。实际上,shell 轻松地构建了命令行(冒号,后跟$param
is 的值,无论赋值是否发生),然后执行命令;碰巧 ':' 没有注意到它所给出的参数。
但我不明白。我明白了:
,true
但是表达式中有两个冒号。作为一个小问题,为什么这个习惯用法在所有 Bourne shell 衍生产品中使用得如此之多?它有什么目的?
笔记: 我对这个习语在两者中的作用感兴趣巴什并在桀骜。
谢谢
答案1
让我们把它分解成几个部分。
此代码运行带有一些参数的命令:
。该命令:
不执行任何操作并忽略其参数。因此,除了参数中发生的任何副作用之外,整个命令行什么也不做。
该语法${parameter_name:=value}
存在于所有非古董 Bourne 风格的 shell 中,包括 ash、bash、ksh 和 zsh。如有必要,它将参数设置为默认值。它相当于
if [ -z "$parameter_name" ]; then parameter_name=value; fi
… ${parameter_name}
也就是说,如果parameter_name
没有设置或者设置为空值,则将其设置为指示值;然后使用新的参数值运行该命令。有一个变体,${parameter_name=value}
如果参数为空,则将其保留为空,如果参数未设置,则仅使用指示的值。
您会发现此语法记录在“参数扩展”下POSIX 规范,以及 dash、bash、ksh 和 zsh 手册。
此语法有多种变体,特别${parameter_name:-value}
是允许您仅对此扩展使用默认值,而不分配给参数。
总结起来: ${parameter_name:=value}
就是一种简洁的写法
if [ -z "$parameter_name" ]; then parameter_name=value; fi
答案2
:
并不意味着 true - 您可能会想到while :
,但即使在该表达式中,它也不意味着“true”,它只是碰巧对其求值(事实上,它只是一个空命令,或 noop)。
该参数扩展 ( ${x:=y}
) 的意思是“分配y到X如果X未设置或为空,并扩展最终值X”。
$ echo "${foo:=bar}"
bar
$ foo=baz
$ echo "${foo:=bar}"
baz
$ foo=
$ echo "${foo:=bar}"
bar
$ echo "${foo}"
bar
Bash Hackers wiki 有一篇关于参数扩展的好文章这里。
使用的原因:
是,虽然命令的其他部分被评估,但它们不会被执行(就像:
空命令一样)。这样,你就已经${x:=y}
执行了它的功能,而不会影响其他任何东西,例如,如果你一开始没有:
,它会尝试执行一个名为y。
这是bash
的帮助页面:
:
:: :
Null command.
No effect; the command does nothing.
Exit Status:
Always succeeds.
答案3
第一个:
是命令,称为“noop”或“无操作”。正如联机帮助页中所述,它通常用于评估参数。
第二个:
是变量扩展中的限定符——从技术上来说确实如此:=
。如前所述,如果没有值,则设置该值。
从习惯用法来看,如果您需要环境变量的默认值,那么您可以使用此语法。例如,当通过 运行程序时cron(8)
,未设置环境,并且 shell 的点文件也不会运行。所以你可能需要设置一些默认值。
: ${JAVA_HOME:=/usr/local/jdk-1.6.0_28}
然后您可以“设置它并忘记它”(直到默认 jvm 更改)。