命令替换能够重新分配一个[1] 甚至是多个命令的输出; 它会将命令的输出如实地添加到另一个上下文中. [2]
命令替换的典型用法形式, 是使用后置引用(`...`). 使用后置引用的(反引号)命令会产生命令行文本.
1 script_name=`basename $0` 2 echo "The name of this script is $script_name." |
这样一来, 命令的输出就能够保存到变量中, 或者传递到另一个命令中作为这个命令的参数, 甚至可以用来产生for循环的参数列表. .
1 rm `cat filename` # "filename"包含了需要被删除的文件列表. 2 # 3 # S. C. 指出, 这种使用方法可能会产生"参数列表太长"的错误. 4 # 更好的方法是 xargs rm -- < filename 5 # ( -- 同时涵盖了某些特殊情况, 这种特殊情况就是, 以"-"开头的文件名会产生不良结果.) 6 7 textfile_listing=`ls *.txt` 8 # 变量中包含了当前工作目录下所有的*.txt文件. 9 echo $textfile_listing 10 11 textfile_listing2=$(ls *.txt) # 这是命令替换的另一种形式. 12 echo $textfile_listing2 13 # 同样的结果. 14 15 # 如果将文件列表放入到一个字符串中的话, 16 # 可能会混入一个新行. 17 # 18 # 一种安全的将文件列表传递到参数中的方法就是使用数组. 19 # shopt -s nullglob # 如果不匹配, 那就不进行文件名扩展. 20 # textfile_listing=( *.txt ) 21 # 22 # 感谢, S.C. |
命令替换将会调用一个subshell. |
命令替换可能会引起单词分割(word split).
即使没有引起单词分割(word split), 命令替换也会去掉多余的新行.
|
如果用echo命令输出一个未引用变量, 而且这个变量以命令替换的结果作为值, 那么这个变量中的换行符将会被删除. 这可能会引起一些异常状况.
|
命令替换甚至允许将整个文件的内容放到变量中, 可以使用重定向或者cat命令.
1 variable1=`<file1` # 将"file1"的内容放到"variable1"中. 2 variable2=`cat file2` # 将"file2"的内容放到"variable2"中. 3 # 但是这行将会fork一个新进程, 4 #+ 所以这行代码将会比第一行代码执行得慢. 5 6 # 注意: 7 # 变量中可以包含空白, 8 #+ 甚至是(厌恶至极的), 控制字符. |
1 # 摘录自系统文件, /etc/rc.d/rc.sysinit 2 #+ (这是红帽系统中的) 3 4 5 if [ -f /fsckoptions ]; then 6 fsckoptions=`cat /fsckoptions` 7 ... 8 fi 9 # 10 # 11 if [ -e "/proc/ide/${disk[$device]}/media" ] ; then 12 hdmedia=`cat /proc/ide/${disk[$device]}/media` 13 ... 14 fi 15 # 16 # 17 if [ ! -n "`uname -r | grep -- "-"`" ]; then 18 ktag="`cat /proc/version`" 19 ... 20 fi 21 # 22 # 23 if [ $usb = "1" ]; then 24 sleep 5 25 mouseoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=02"` 26 kbdoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=01"` 27 ... 28 fi |
变量替换允许将一个loop的输出设置到一个变量中. 这么做的关键就是将循环中echo命令的输出全部截取.
例子 14-2. 将一个循环输出的内容设置到变量中
1 #!/bin/bash 2 # csubloop.sh: 将循环输出的内容设置到变量中. 3 4 variable1=`for i in 1 2 3 4 5 5 do 6 echo -n "$i" # 对于在这里的命令替换来说 7 done` #+ 这个'echo'命令是非常关键的. 8 9 echo "variable1 = $variable1" # variable1 = 12345 10 11 12 i=0 13 variable2=`while [ "$i" -lt 10 ] 14 do 15 echo -n "$i" # 再来一个, 'echo'是必需的. 16 let "i += 1" # 递增. 17 done` 18 19 echo "variable2 = $variable2" # variable2 = 0123456789 20 21 # 这就证明了在一个变量的声明中 22 #+ 嵌入一个循环是可行的. 23 24 exit 0 |
命令替换使得扩展有效Bash工具集变为可能 这样, 写一段小程序或者一段脚本就可以达到目的. 因为程序或脚本的输出会传到stdout上(就像一个标准UNIX工具所做的那样), 然后重新将这些输出保存到变量中. (译者: 作者的意思就是在这种情况下写脚本和写程序作用是一样的.)
|
对于命令替换来说, $(COMMAND)形式已经取代了后置引用"`".
$(...)形式的命令替换在处理双反斜线(\\)时与`...`形式不同.
$(...)形式的命令替换是允许嵌套的. [3]
或者, 可以更加灵活 . . . 例子 14-3. 找anagram(回文构词法, 可以将一个有意义的单词, 变换为1个或多个有意义的单词, 但是还是原来的子母集合)
|
命令替换在脚本中使用的例子:
[1] | 对于命令替换来说, 这个命令既可以是外部的系统命令, 也可以是内部脚本的内建命令, 甚至可以是脚本函数. | |
[2] | 从技术的角度来讲, 命令替换将会抽取一个命令的输出, 然后使用=操作将其赋值到一个变量中. | |
[3] | 事实上, 对于后置引用的嵌套是可行的, 但是只能将内部的反引号转义才行, 就像John默认指出的那样.
|