[转载]shell中的冒号

作者 by adtxl / 2021-08-04 / 暂无评论 / 695 个足迹

用法1

{str:=expr}

如果变量str不为空,${str:=expr}就等于str的值,若str为空,就把expr的值赋值给str。

用法2

用途说明

我们知道,在Linux系统中,冒号(:)常用来做路径的分隔符(PATH),数据字段的分隔符(/etc/passwd)等。其实,冒号(:)在Bash中也是一个内建命令,它啥也不做,是个空命令、只起到占一个位置的作用,但有时候确实需要它。当然,它也有它的用途的,否则没必要存在。在Linux的帮助页中说它除了参数扩展和重定向之外不产生任何作用。

常用参数

啥也不做,只起到占位符的作用。比如在编写脚本的过程中,某些语法结构需要多个部分组成,但开始阶段并没有想好或完成相应的代码,这时就可以用:来做占位符,否则执行时就会报错。

if [ "today" == "2011-08-29" ]; then
    :
else
    :
fi

格式:: your comment here

格式:# your comment here

写代码注释(单行注释)。

格式:: 'comment line1

comment line2

more comments'

写多行注释。
格式:: >file

格式:>file

清空文件file的内容。
格式:: ${VAR:=DEFAULT}

当变量VAR没有声明或者为NULL时,将VAR设置为默认值DEFAULT。如果不在前面加上:命令,那么就会把${VAR:=DEFAULT}本身当做一个命令来执行,报错是肯定的。

使用示例
示例一 参数扩展
[root@node56 ~]# : abc=1234
[root@node56 ~]# echo $abc

[root@node56 ~]# : ${abc:=1234}
[root@node56 ~]# echo $abc
1234

[root@node56 ~]# ${abc:=1234}
-bash: 1234: command not found
[root@node56 ~]#

示例二 清空文件
[root@node56 ~]# cat <<<"Hello" >123.txt
[root@node56 ~]# cat 123.txt
Hello
[root@node56 ~]# : >123.txt
[root@node56 ~]# cat 123.txt
[root@node56 ~]#

示例三 脚本注释、占位符
脚本test_colon.sh

#!/bin/sh

: this is single line comment

: 'this is a multiline comment,
second line
end of comments'

if [ "1" == "1" ]; then
        echo "yes"
else
        :
fi

[root@node56 ~]# ./test_colon.sh
yes
[root@node56 ~]#

文章3

冒号命令本身没什么副作用,使用场景有限,一般用于参数扩展,有以下几种用法:

${parameter:-word}    如果parameter没有设置或者为空,替换为word;否则替换为parameter的值。
${parameter:+word}    如果parameter没有设置或者为空,不进行任何替换;否则替换为word。
${parameter:=word}    如果parameter没有设置或者为空,把word赋值给parameter。最终替换为parameter的值。
${parameter:?word}    如果parameter没有设置或者为空,把word输出到stderr,否则替换为parameter的值。
${parameter:offset}    扩展为parameter中从offset开始的子字符串。
${parameter:offset:length}     扩展为parameter中从offset开始的长度不超过length的字符。

例如:

$ foo=hellobash
$ echo ${foo}
hellobash
$ echo ${foo:-newword}
hellobash
$ echo ${foo}
hellobash
$ echo ${foo:+newword}
newword
$ echo ${foo}
hellobash
$ echo ${foo:?newword}
hellobash
$ echo ${foo}
hellobash
$ echo ${foo:=newword}
hellobash
$ echo ${foo}
hellobash
$ unset foo
$ echo ${foo}

$ echo ${foo:-newword}
newword
$ echo ${foo}

$ echo ${foo:+newword}

$ echo ${foo}

$ echo ${foo:?newword}
bash: foo: newword
$ echo ${foo}

$ echo ${foo:=newword}
newword
$ echo ${foo}
newword
$ echo ${foo:2}
wword
$ echo ${foo:2:3}
wwo

有时候,冒号命令用作占位符,什么事情也不做,其退出状态为0,如下:

$ :
$ echo $?
0
$ : abc
$ echo $?
0

在shell扩展的模式匹配中,也用到了冒号,用法如下:

[[:class:]]    
通过class指定字符类别,class可以是POSIX标准中的下列关键字:alnum、alpha、ascii、blank、cntrl、digit、graph、lower、print、punct、space、upper、word、xdigit,其中word表示大小写字母、数字和下划线。

例如下面例子中的字符串替换(数字替换为0,小写字母替换为x,大写字母替换为X):

var=helloBASH123
$ echo $var
helloBASH123
$ echo ${var//[[:digit:]]/0}
helloBASH000
$ echo ${var//[[:lower:]]/x}
xxxxxBASH123
$ echo ${var//[[:upper:]]/X}
helloXXXX123

在shell的数学运算中,支持像其它编程语言一样的三元运算符,其中就用到了冒号,如下:

$ var=100
$ echo $var
100
$ (($var>100?var++:var--))
~$ echo $var
99

另外,在shell中冒号还用作变量间的分隔符,例如环境变量PATH。

Makefile中的冒号:

1.赋值的时候用;

2.目标依赖关系

3.还用于分隔不同的目录,如:

SRC_PATH ?= .:..

风格1: 递归扩展变量

变量定义格式是,变量和值之间用等号,即 =
例如:

foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:;echo $(foo)

将显示 Huh?

再例如:

CFLAGS = $(include_dirs) -O
include_dirs = -Ifoo -Ibar

缺点是不能这么定义:CFLAGS = $(CFLAGS) -O,将会死循环

风格2: 简单扩展变量

变量定义格式是,变量和值之间用冒号等号,即 :=
例如

x := foo
y := $(x) bar
x := later

等价于:

y := foo bar
x := later

另外 ?= 含义为:没有定义则赋值

FOO ?= bar

等价于

ifeq ($(origin FOO), undefined)
FOO = bar
endif

+= 是为变量后面追加字符

变量替换

$(var:a=b),是将 var 变量中每一个单词后面的 a 替换为 b

$(var:suffix=replacement)等价于$(patsubst %suffix,%replacement,$(var))
$(foo:%.o=%.c) ,由于出现了 %,其功能和 patsubst 等价

$(var:pattern=replacement)等价于$(patsubst pattern,replacement,$(var))

转载自:
1.shell中冒号的意义

2.我使用过的Linux命令之:(冒号) - 啥也不做(除了……)

3.【Bash百宝箱】shell内建命令之冒号

独特见解