DQd*_*dlM 27 shell shell-script
在关于 shell scripting 中的注释的这个问题的答案中,表明:
是一个空命令,它明确地不做任何事情(但不用于注释)。
一个什么都不做的命令有什么用?
Mad*_*ist 20
我通常true
在循环中使用;我认为它更清楚:
while true; do
...
done
Run Code Online (Sandbox Code Playgroud)
我发现一个:
非常方便的地方是 case 语句,如果您需要匹配某些内容但实际上不想做任何事情。例如:
case $answer in
([Yy]*) : ok ;;
(*) echo "stop."; exit 1 ;;
esac
Run Code Online (Sandbox Code Playgroud)
Arc*_*ege 13
最初,它用于确定它是一个 Bourne shell 程序,而不是 C 编译程序。这是在 shebang 和多种脚本语言(csh、perl)之前。您仍然可以运行仅以:
以下开头的脚本:
$ echo : > /tmp/xyzzy
$ chmod +x /tmp/xyzzy
$ ./xyzzy
Run Code Online (Sandbox Code Playgroud)
它通常会针对$SHELL
(或/bin/sh
)运行脚本。
从那时起,主要用途是评估参数。我还在用:
: ${EDITOR:=vim}
Run Code Online (Sandbox Code Playgroud)
在脚本中设置默认值。
Kyl*_*nes 11
:
对于编写必须从内部终止的循环很有用。
while :
do
...stuff...
done
Run Code Online (Sandbox Code Playgroud)
这将永远运行,除非break
或exit
被调用,或者外壳收到终止信号。
Bru*_*ger 10
当您需要在 shell 脚本中使用“除非”语句时,您可以使用“not”条件,这对于某些测试来说可能看起来很愚蠢,或者您在 true 子句中使用 ':',在 false 中使用真实代码 -条款。
if [ some-exotic-condition ]
then
:
else
# Real code here
fi
Run Code Online (Sandbox Code Playgroud)
“异国情调”可能是你不想否定的东西,或者如果你不使用“否定逻辑”,那就更清楚了。
除了 # 字符之外,我只使用过这个来临时注释一行,在注释行会产生语法错误的情况下,由于 shell 语法中的一个缺陷,不允许使用空命令序列:
if condition ; then
:# temporarily commented out command
fi
Run Code Online (Sandbox Code Playgroud)
没有 : 我们缺少一个命令序列,这是一个语法错误。
我觉得有两种情况:
很有用:
#!/bin/sh
# set VAR to "default value" if not already set in the environment
: "${VAR=default value}"
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR}"
Run Code Online (Sandbox Code Playgroud)
这是一种方便的方式,允许您的 shell 脚本用户在不编辑脚本的情况下覆盖设置。(但是,命令行参数更好,因为如果用户巧合地拥有您在其导出环境中使用的变量,您不会冒意外行为的风险。)以下是用户将如何覆盖设置:
VAR="other value" ./script
Run Code Online (Sandbox Code Playgroud)
该${VAR=value}
语法说要集VAR
到value
如果VAR
尚未设置,然后展开对变量的值。由于我们暂时不关心变量的值,因此将其作为参数传递给 no-op 命令:
以将其丢弃。
即使:
是一个无操作命令,:
在运行:
命令之前,扩展是由 shell(而不是命令!)执行的,因此变量分配仍然发生(如果适用)。
也可以使用true
或 一些其他命令代替:
,但代码变得更难阅读,因为意图不太明确。
以下脚本也适用:
#!/bin/sh
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR=default value}"
Run Code Online (Sandbox Code Playgroud)
但是上面的维护起来要困难得多。如果在该行${VAR}
上方添加了一行 using printf
,则必须移动默认分配扩展。如果开发人员忘记移动该分配,则会引入错误。
通常应该避免使用空的条件块,但它们有时很有用:
if some_condition; then
# todo: implement this block of code; for now do nothing.
# the colon below is a no-op to prevent syntax errors
:
fi
Run Code Online (Sandbox Code Playgroud)
有些人认为,if
与否定测试相比,拥有一个空的 true块可以使代码更易于阅读。例如:
if [ -f foo ] && bar || baz; then
:
else
do_something_here
fi
Run Code Online (Sandbox Code Playgroud)
可以说比以下更容易阅读:
if ! [ -f foo ] || ! bar && ! baz; then
do_something_here
fi
Run Code Online (Sandbox Code Playgroud)
但是我相信有一些替代方法比空的真实块更好:
将条件放入函数中:
exotic_condition() { [ -f foo ] && bar || baz; }
if ! exotic_condition; then
do_something_here
fi
Run Code Online (Sandbox Code Playgroud)将条件放在花括号内(或括号,但括号会产生一个子shell进程,并且在子shell之外对子shell内的环境所做的任何更改都不会在子shell之外可见),然后再否定:
if ! { [ -f foo ] && bar || baz; } then
do_something_here
fi
Run Code Online (Sandbox Code Playgroud)使用||
代替if
:
[ -f foo ] && bar || baz || {
do_something_here
}
Run Code Online (Sandbox Code Playgroud)
当反应是简单的单行时,我更喜欢这种方法,例如断言条件:
log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$@"; exit 1; }
[ -f foo ] && bar || baz || fatal "condition not met"
Run Code Online (Sandbox Code Playgroud)