bash Null运算符“:”的含义是什么,冒号?


13

BASH脚本中“空”运算符的意义是什么?我了解到,if当您无话可说时,它用作命令后的占位符,但需要一个命令才能使程序正常运行。但是,它的总体用途是什么?您什么时候使用它?什么时候使用它有意义?



1
您引用的原因非常重要。为什么需要更多?
terdon 2014年

Answers:


16

有时允许出现参数扩展副作用是很有用的。

例如,设置默认值

read -p "Enter your name: " name
: ${name:=John Doe}  # if the user entered an empty string
echo "$name"

2
您能逐个符号解释第二行如何工作吗?
Ruslan 2014年

在bash手册中阅读有关:命令参数扩展的信息。
glenn jackman 2014年

4
为了概述@glennjackman所引用的内容,第二行调用null命令:,${name:="John Doe"}并将其扩展,导致赋值发生,因为它被视为:的参数。如果不使用:shell将尝试运行“ John Doe”作为命令或该值($name如果已设置)
imkendal

13

您还可以将其用于无限循环:

while : ; do 
   # ....
done

4
但也许while true更具可读性,因为(a)使用较少的标点,以及(b)与C衍生语言更相似。
wchargin

9

您可以使用它来创建文件,而无需运行程序:

: > /path/to/file

这比touch /path/to/file (由于不需要运行touch程序)快得多,并且可能比仅普通的方法具有更高的可移植性。

> /path/to/file

这似乎可以在许多系统上使用。同样,它可用于检查您是否具有文件写权限

if { : >> /path/to/file;} 2> /dev/null
then
    echo "writeable"
else
    echo "write permission denied"
fi

尽管通常也可以在不使用的情况下完成此操作:。注意事项:

  • 这不会检查文件是否已经存在。如果没有,这将在拥有权限的情况下创建文件。
  • 如果该文件不存在,并且您的脚本没有创建该文件的权限,则将报告“写入权限被拒绝”。

(请参阅链接的问题,以了解为什么它比更加可靠if [ -w /path/to/file ]。)


5

追溯到Unix V6和Thompson Shell中,:实际上已将用作goto语句的一部分。根据手册,它最初出现在Unix版本3中:

在整个命令文件中搜索以:开头的行,作为第一个非空白字符,然后是一个或多个空格,然后是标签。如果找到了这样的行,则goto将命令文件偏移量重新定位到标签后的行并退出。这将导致外壳转移到标记的行。

如今,在中bash,它用作无操作运算符,返回成功。确实,如果您查看源代码,将会看到两者,true并在下面:使用了相同的功能int colon_builtin()。没有:非内置命令,/bin/true实际上是一个相当大的命令

:可以在任何使用过的地方true使用,例如在中command_that_can_fail || true,尽管这可能会使非专家感到困惑。在此处了解更多信息。


3

if当您只想在负面方面做某事时,可以在命令的正面测试中使用它。例如:

if [[ True == False ]]; then
    :
else
    echo "true <> flase"
fi

没有:bash会产生语法错误。

这是一个过于简化的示例。通常,当您尚未编写该代码段并且只需要不产生错误的内容时,便会在初步编码中使用这种技术。


好的答案(虽然一开始可能并不明显)对于在测试条件下的实际命令最有用,例如if pgrep firefox >/dev/null ; then : ; else echo "Firefox not running"; fi,只有在不运行Firefox时才会显示错误。换句话说,只有在命令有错误时才需要做某事。从某种意义上讲,它等效于pgrep firefox || echo "Firefox not running",尽管可读性更好,并允许更多命令
Sergiy Kolodyazhnyy

0

我只是在带有SSH命令的脚本中使用了它,以防止脚本出错。

在这种情况下,我想查看用户是否可以连接到一组服务器。如果连接正常,则远程主机将回显正常。如果连接失败,SSH将以错误响应。但是,如果脚本失败,我希望脚本以0而不是SSH命令的值退出。因此,从本质上讲,我通过||使用null命令对SSH错误进行“或”操作来捕获它:。看起来像这样:

#!/bin/bash
for i in $(cat servers.txt); do
    echo -n "$i "; 
    ssh user@${i} 'echo OK' || :; 
done

这样,我从SSH获取输出,但没有错误代码:

....
swl06 ok
swl07 ok
swl08 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
swl09 ok
swl10 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
....
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.