一个什么都不做的命令,只不过是一个注释引导,但实际上是一个内置的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

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


当前回答

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

日志记录

以这个示例脚本为例:

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打印一些输出时,它使电子邮件主题看起来更好看。

其他回答

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

: `some_command`

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

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

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

:> file.log

我在一个脚本中看到了这种用法,并认为它可以很好地替代在脚本中调用basename。

oldIFS=$IFS  
IFS=/  
for basetool in $0 ; do : ; done  
IFS=$oldIFS  

... 这是替换代码:baseool =$(basename $0)

自我记录的功能

您还可以使用:将文档嵌入到函数中。

假设您有一个库脚本mylib.sh,它提供了各种函数。您可以将库(。Mylib.sh),然后直接调用函数(lib_function1 arg1 arg2),或者避免使您的命名空间混乱,并使用函数参数调用库(Mylib.sh lib_function1 arg1 arg2)。

如果您还可以输入mylib.sh——help并获得可用函数及其用法的列表,而不必在帮助文本中手动维护函数列表,这不是很好吗?

#!/bin/bash

# all "public" functions must start with this prefix
LIB_PREFIX='lib_'

# "public" library functions
lib_function1() {
    : This function does something complicated with two arguments.
    :
    : Parameters:
    : '   arg1 - first argument ($1)'
    : '   arg2 - second argument'
    :
    : Result:
    : "   it's complicated"

    # actual function code starts here
}

lib_function2() {
    : Function documentation

    # function code here
}

# help function
--help() {
    echo MyLib v0.0.1
    echo
    echo Usage: mylib.sh [function_name [args]]
    echo
    echo Available functions:
    declare -f | sed -n -e '/^'$LIB_PREFIX'/,/^}$/{/\(^'$LIB_PREFIX'\)\|\(^[ \t]*:\)/{
        s/^\('$LIB_PREFIX'.*\) ()/\n=== \1 ===/;s/^[ \t]*: \?['\''"]\?/    /;s/['\''"]\?;\?$//;p}}'
}

# main code
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
    # the script was executed instead of sourced
    # invoke requested function or display help
    if [ "$(type -t - "$1" 2>/dev/null)" = function ]; then
        "$@"
    else
        --help
    fi
fi

关于代码的一些注释:

All "public" functions have the same prefix. Only these are meant to be invoked by the user, and to be listed in the help text. The self-documenting feature relies on the previous point, and uses declare -f to enumerate all available functions, then filters them through sed to only display functions with the appropriate prefix. It is a good idea to enclose the documentation in single quotes, to prevent undesired expansion and whitespace removal. You'll also need to be careful when using apostrophes/quotes in the text. You could write code to internalize the library prefix, i.e. the user only has to type mylib.sh function1 and it gets translated internally to lib_function1. This is an exercise left to the reader. The help function is named "--help". This is a convenient (i.e. lazy) approach that uses the library invoke mechanism to display the help itself, without having to code an extra check for $1. At the same time, it will clutter your namespace if you source the library. If you don't like that, you can either change the name to something like lib_help or actually check the args for --help in the main code and invoke the help function manually.

它类似于Python中的传递。

一种用法是将一个函数存根,直到它被写入:

future_function () { :; }