Answers:
$(command)
是“命令替换”。如您所知,它运行command
,捕获其输出,然后将其插入到包含$(…)
; 的命令行中。例如,
$ ls -ld $(date +%B).txt
-rwxr-xr-x 1 Noob Noob 867 Jul 2 11:09 July.txt
${parameter}
是“参数替换”。在shell的手册页bash(1)的“ Parameter Expansion ”标题下可以找到很多信息:
${parameter}
参数 的值被替换。当parameter是一个多于一位数字的位置参数时,或者当parameter后跟一个不被解释为其名称一部分的字符时,必须使用大括号。
有关位置参数,请参见下面的“ 位置参数 ”。如其他答案所示,最常见的用法
parameter
是变量名。${…}
如上段结尾所述,该格式使您可以获取变量的值(即),并紧跟其后的字母,数字或下划线:$variable_name
$动物=猫 $ echo $动物 #没有诸如 “动物”之类的变量。 $ echo $ {animal} s 猫 $ echo $ animal_food #没有这样的变量 “ animal_food”。 $ echo $ {animal} _food 猫食
您也可以使用引号:
$ echo“ $ animal” s 猫
或者,作为选项的练习,您可以使用第二个变量:
$ plural = s $ echo $ animal $ plural 猫
但这只是第1步。手册页中的下一段很有趣,尽管有点神秘:
如果参数的第一个字符
是感叹号(!
),则会引入可变间接级别。Bash使用由其余参数形成的变量的值作为变量
的名称;然后扩展该变量,并在其余替换中使用该值,而不是参数本身的值。这称为间接扩展。
… (例外) …
感叹号必须紧随左括号之后才能引入间接功能。
除了示例以外,我不确定如何使它更清晰:
$动物=猫 $ echo $动物 猫 $ cat =平头 $ echo $ cat 虎斑猫 $ echo $ {!animal} tabby #如果 $ animal 是 “ cat” ,则 $ {!animal} 是 $ cat ,即 “ tabby”
因此,我们将该步骤称为1½。第2步可以做很多有趣的事情:
$动物=猫 $ echo $ {#animal} 3 #字符串长度 $ echo $ {animal / at / ow} 牛 #替代
你不能做任何的那些东西没有{
...... }
括号。
位置参数
考虑以下人工示例:
$猫myecho.sh 回声$ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 $ 11 $ 12 $ 13 $ 14 $ 15 $ ./myecho.sh嘿,骗人的骗子,猫和小提琴,那头牛跳上了月亮。 嘿,骗子,猫和小提琴,嘿,嘿1,嘿2,嘿3,嘿4,嘿5
因为外壳不理解$10
,$11
等等。它$10
像对待一样${1}0
。但它确实明白${10}
,${11}
等,在手册页(“超过一个数字的位置参数”)中提到。
但是实际上不要编写这样的脚本;有更好的方法来处理较长的参数列表。
上面的内容(以及许多其他形式的构造)在shell的手册页bash(1)中进行了更详细的讨论。${parameter…something_else}
报价单
请注意,除非有充分的理由不这样做,否则应始终引用shell变量,并且确保您知道自己在做什么。相比之下,大括号可能很重要,但不如引号重要。
$ filename =“ nursery rhyme.txt” $ ls -ld $ {文件名} ls:无法访问托儿所:没有此类文件或目录 ls:无法访问rhyme.txt:没有此类文件或目录 $ ls -ld“ $文件名” -rwxr-xr-x 1 Noob Noob 5309 7月2日11:09 Nursery rhyme.txt
这也适用于位置参数(即命令行参数;例如"$1"
)以及命令替换:
$ ls -ld $(日期“ +%B%Y”)。txt ls:无法访问7月:没有此类文件或目录 ls:无法访问2015.txt:没有此类文件或目录 $ ls -ld“ $(date” +%B%Y“)。txt” -rwxr-xr-x 1 Noob Noob 687 Jul 2 11:09 July 2015.txt
有关
引号和… 之间的交互的简要论述,请参见在命令替换中未转义的Bash引号。$(
)
!
。
${!animal}
实际上是在指变量$cat
而不是值cat。”是的,这就是重点。“ / at在回声$ {animal / at / ow}中如何变成“ c”?”嗯?/ at不会变成“ c”;当“ at”替换为“ ow”时,“ cat”变为“ cow”。
我通常在字符串中更常见。这样的事情是行不通的:
var="a"
echo "$varRAW_STRING"
但这将:
var="a"
echo "${var}RAW_STRING"
就像您正确说的,$()
用于执行命令:
dir_contents=$(ls)
您也可以使用反引号,但我发现它$()
用途更广。一方面,反引号不能(轻松)嵌套。
date_directory=`ls `date '+%Y-%m-%d'`` # Makes no sense
date_directory=$(ls $(date '+%Y-%m-%d')) # Much better
date_directory=`ls \`date '+%Y-%m-%d'\``
。但这是丑陋的。$(…)
更清晰易用。
`…`
是数年前发明的(唯一的)用于命令替换的语法$(…)
,因此您无需想像任何东西,人们已经做到了。
${
variable_name
}