一个什么都不做的命令,只不过是一个注释引导,但实际上是一个内置的shell,它的目的是什么?

它比每次调用在脚本中插入注释要慢40%左右,这可能取决于注释的大小。我认为唯一可能的原因是:

# poor man's delay function
for ((x=0;x<100000;++x)) ; do : ; done

# inserting comments into string of commands
command ; command ; : we need a comment in here for some reason ; command

# an alias for `true'
while : ; do command ; done

我想我真正想要的是它在历史上的应用。


当前回答

:也可以是块注释(类似于C语言中的/* */)。例如,如果你想在脚本中跳过一段代码,你可以这样做:

: << 'SKIP'

your code block here

SKIP

其他回答

从历史上看,Bourne shell并没有内置的true和false命令。True被改成了:,false被改成了let 0。

:在可移植性方面比真实的稍微好一些。作为一个简单的例子,考虑没有!管道操作符或||列表操作符(就像一些古老的Bourne shell的情况一样)。这使得if语句的else子句成为基于退出状态进行分支的唯一方法:

if command; then :; else ...; fi

因为if要求一个非空的then子句和注释不算作非空,:作为一个no-op。

现在(在现代语境中)你通常可以用:或者true。两者都是由POSIX指定的,其中一些发现true更容易阅读。然而,有一个有趣的区别::是所谓的POSIX特殊内置,而true是常规内置。

Special built-ins are required to be built into the shell; Regular built-ins are only "typically" built in, but it isn't strictly guaranteed. There usually shouldn't be a regular program named : with the function of true in PATH of most systems. Probably the most crucial difference is that with special built-ins, any variable set by the built-in - even in the environment during simple command evaluation - persists after the command completes, as demonstrated here using ksh93: $ unset x; ( x=hi :; echo "$x" ) hi $ ( x=hi true; echo "$x" ) $ Note that Zsh ignores this requirement, as does GNU Bash except when operating in POSIX compatibility mode, but all other major "POSIX sh derived" shells observe this including dash, ksh93, and mksh. Another difference is that regular built-ins must be compatible with exec - demonstrated here using Bash: $ ( exec : ) -bash: exec: :: not found $ ( exec true ) $ POSIX also explicitly notes that : may be faster than true, though this is of course an implementation-specific detail.

你可以将它与反撇号(' ')结合使用来执行命令而不显示输出,如下所示:

: `some_command`

当然,你可以只执行some_command > /dev/null,但是:-version稍微短一些。

话虽如此,我不建议这样做,因为这会让人们感到困惑。它只是作为一个可能的用例出现在脑海中。

:也可以是块注释(类似于C语言中的/* */)。例如,如果你想在脚本中跳过一段代码,你可以这样做:

: << 'SKIP'

your code block here

SKIP

如果你想把一个文件截断为零字节,这对清除日志很有用,试试这个:

:> file.log

其他答案中没有提到的两个用法:

日志记录

以这个示例脚本为例:

set -x
: Logging message here
example_command

第一行set -x使shell在运行命令之前打印出该命令。这是一个非常有用的结构。缺点是通常的echo Log消息类型的语句现在打印两次消息。冒号方法避开了这个问题。请注意,您仍然必须转义特殊字符,就像您对echo所做的那样。

Cron职位名称

我看到它在cron作业中被使用,像这样:

45 10 * * * : Backup for database ; /opt/backup.sh

这是一个cron作业,每天在10:45运行脚本/opt/backup.sh。这种技术的优点是,当/opt/backup.sh打印一些输出时,它使电子邮件主题看起来更好看。