如何使用双括号或单括号,括号,大括号
我对Bash中的括号,括号,大括号的使用以及它们的双重或单一forms的区别感到困惑。 有没有明确的解释?
在Bash中, test
和[
内置。
双括号支持附加function。 例如,您可以使用&&
和||
而不是-a
和-o
并且有一个匹配operator =~
的正则expression式。
除了分隔variables名之外,大括号还用于参数扩展,所以您可以执行如下操作:
-
截断variables的内容
$ var="abcde"; echo ${var%d*}
abc
-
进行类似于
sed
replace$ var="abcde"; echo ${var/de/12}
abc12
-
使用默认值
$ default="hello"; unset var; echo ${var:-$default}
hello
-
还有几个
此外,大括号扩展会创build通常在循环中迭代的string列表:
$ echo f{oo,ee,a}d food feed fad $ mv error.log{,.OLD} (error.log is renamed to error.log.OLD because the brace expression expands to "mv error.log error.log.OLD") $ for num in {000..2}; do echo "$num"; done 000 001 002 $ echo {00..8..2} 00 02 04 06 08 $ echo {D..T..4} DHLPT
请注意,前导零和增量function在Bash 4之前不可用。
感谢gboffi提醒我关于大括号的扩展。
双括号用于算术运算 :
((a++)) ((meaning = 42)) for ((i=0; i<10; i++)) echo $((a + b + (14 * c)))
它们使您可以省略整数和数组variables的美元符号,并在运算符周围包含空格以提高可读性。
单个括号也用于数组索引:
array[4]="hello" element=${array[index]}
右边的(大多数/全部?)数组引用需要大括号。
ephemient的评论提醒我括号也用于subshell。 而且它们被用来创build数组。
array=(1 2 3) echo ${array[1]} 2
-
单个括号(
[
)通常实际上调用名为[
;man test
或man [
更多信息。 例:$ VARIABLE=abcdef $ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi yes
-
双括号(
[[
)与单个括号完全相同(基本上),但是是bash内build的。$ VARIABLE=abcdef $ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi no
-
圆括号(
()
)用于创build子shell。 例如:$ pwd /home/user $ (cd /tmp; pwd) /tmp $ pwd /home/user
正如你所看到的,subshell允许你在不影响当前shell环境的情况下执行操作。
4A。 大括号( {}
)用于明确标识variables。 例:
$ VARIABLE=abcdef $ echo Variable: $VARIABLE Variable: abcdef $ echo Variable: $VARIABLE123456 Variable: $ echo Variable: ${VARIABLE}123456 Variable: abcdef123456
4B。 大括号也用于在当前 shell环境中执行一系列命令,例如
$ { date; top -b -n1 | head ; } >logfile # 'date' and 'top' output are concatenated, # could be useful sometimes to hunt for a top loader ) $ { date; make 2>&1; date; } | tee logfile # now we can calculate the duration of a build from the logfile
虽然( ( )
有一个微妙的语法差异,但(见bash参考 ); 本质上是一个分号;
在括号内的最后一个命令是必须的,并且大括号{
, }
必须被空格包围。
括号
if [ CONDITION ] Test construct if [[ CONDITION ]] Extended test construct Array[1]=element1 Array initialization [az] Range of characters within a Regular Expression $[ expression ] A non-standard & obsolete version of $(( expression )) [1]
[1] http://wiki.bash-hackers.org/scripting/obsolete
大括号
${variable} Parameter substitution ${!variable} Indirect variable reference { command1; command2; . . . commandN; } Block of code {string1,string2,string3,...} Brace expansion {a..z} Extended brace expansion {} Text replacement, after find and xargs
括号
( command1; command2 ) Command group executed within a subshell Array=(element1 element2 element3) Array initialization result=$(COMMAND) Command substitution, new style >(COMMAND) Process substitution <(COMMAND) Process substitution
双括号
(( var = 78 )) Integer arithmetic var=$(( 20 + 5 )) Integer arithmetic, with variable assignment (( var++ )) C-style variable increment (( var-- )) C-style variable decrement (( var0 = var1<98?9:21 )) C-style ternary operation
我只是想从TLDP中添加这些:
~:$ echo $SHELL /bin/bash ~:$ echo ${#SHELL} 9 ~:$ ARRAY=(one two three) ~:$ echo ${#ARRAY} 3 ~:$ echo ${TEST:-test} test ~:$ echo $TEST ~:$ export TEST=a_string ~:$ echo ${TEST:-test} a_string ~:$ echo ${TEST2:-$TEST} a_string ~:$ echo $TEST2 ~:$ echo ${TEST2:=$TEST} a_string ~:$ echo $TEST2 a_string ~:$ export STRING="thisisaverylongname" ~:$ echo ${STRING:4} isaverylongname ~:$ echo ${STRING:6:5} avery ~:$ echo ${ARRAY[*]} one two one three one four ~:$ echo ${ARRAY[*]#one} two three four ~:$ echo ${ARRAY[*]#t} one wo one hree one four ~:$ echo ${ARRAY[*]#t*} one wo one hree one four ~:$ echo ${ARRAY[*]##t*} one one one four ~:$ echo $STRING thisisaverylongname ~:$ echo ${STRING%name} thisisaverylong ~:$ echo ${STRING/name/string} thisisaverylongstring
testing [和[[在BashFAQ中详细解释]之间的区别 。
长话短说:testing实现了命令的旧的,可移植的语法。 在几乎所有炮弹中(最老的伯恩炮弹都是例外),[是testing的同义词(但需要最后一个参数)。 虽然所有现代的shell都有内置的[],但通常还有一个名字的外部可执行文件,例如/ bin / [。
[是它的一个新的改进版本,这是一个关键字,而不是一个程序。 这对易用性有好处,如下所示。 [可以被KornShell和BASH(例如2.03)理解,但不能被旧的POSIX或BourneShell理解。
结论是:
新的testing命令何时应该使用[和什么时候使用旧的[? 如果考虑到BourneShell的可移植性,则应该使用旧的语法。 另一方面,如果脚本需要BASH或KornShell,则新的语法更为灵活。
函数定义中的圆括号
函数定义中使用括号()
:
function_name () { command1 ; command2 ; }
这就是为什么即使在命令参数中也必须避免括号的原因:
$ echo ( bash: syntax error near unexpected token `newline' $ echo \( ( $ echo () { command echo The command echo was redefined. ; } $ echo anything The command echo was redefined.