Noo*_*oob 39 linux centos script shell ubuntu
$ echo $(date)
Thu Jul 2 16:33:11 SGT 2015
$ echo ${date}
$ name=foo
$ echo $(name)
ksh: name: not found
$ echo ${name}
foo
Run Code Online (Sandbox Code Playgroud)
似乎 ${variable} 与 $variable 相同。而 $() 是执行命令。那么为什么要使用 ${} 呢?
G-M*_*ca' 59
$(command)
是“命令替换”。正如您所理解的,它运行command
,捕获其输出,并将其插入到包含$(…)
;的命令行中。例如,
$ ls -ld $(date +%B).txt
-rwxr-xr-x 1 Noob Noob 867 Jul 2 11:09 July.txt
Run Code Online (Sandbox Code Playgroud)
${parameter}
是“参数替换”。在 shell 的手册页bash(1) 中的“参数扩展”标题下可以找到很多信息:
${parameter}
参数 的值被替换。当参数是一个多于一位的位置参数时,或者当参数后跟一个不被解释为其名称的一部分的字符时,需要大括号。
有关位置参数,请参阅下面的“位置参数”。如其他答案所示,最常见的用法
parameter
是变量名。${…}
如上一段末尾所述,该形式可让您获取变量的值(即),并在其后紧跟字母、数字或下划线:$variable_name
$动物=猫 $ echo $animals # 没有像“animals”这样的变量。 $ echo ${animal}s 猫 $ echo $animal_food # 没有像“animal_food”这样的变量。 $ echo ${animal}_food 猫食
你也可以用引号来做到这一点:
$ echo "$animal"s 猫
或者,作为选项练习,您可以使用第二个变量:
$复数=s $ echo $animal$plural 猫
但这只是第一步。手册页中的下一段很有趣,虽然有点神秘:
如果参数的第一个字符
是感叹号 ( !
),则引入了一个变量间接级别。Bash 使用由参数的其余部分形成的变量的值作为变量
的名称;这个变量然后被扩展,并且该值用于替换的其余部分,而不是参数本身的值。这称为间接扩展。?
…… (例外) ……?感叹号必须紧跟在左大括号之后才能引入间接性。
除了示例之外,我不确定如何更清楚地说明这一点:
$动物=猫 $回声$动物 猫 $猫=虎斑猫 $回声 $cat 虎斑猫 $ echo ${!animal} tabby # 如果$animal是“cat” ,那么${!animal}就是$cat ,即“tabby”
因此,我们将该步骤称为 1½。作为第 2 步,您可以做很多有趣的事情:
$动物=猫 $ echo ${#animal} 3 # 字符串长度 $ echo ${animal/at/ow} 牛 # 替换
没有{
……}
大括号,你不能做任何这些事情。
位置参数
考虑这个人为的例子:
$ cat myecho.sh echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $ ./myecho.sh 嘿,diddle dodle,猫和小提琴,牛跳过月亮。 嘿diddlediddle,猫和小提琴,嘿0嘿1嘿2嘿3嘿4嘿5
因为外壳不理解$10
,$11
等。它把它$10
当作${1}0
。但它确实理解${10}
,${11}
等,如手册页中所述(“多于一位的位置参数”)。
但实际上不要写那样的脚本;有更好的方法来处理长参数列表。
以上(以及更多形式的构造)在 shell 的手册页bash(1) 中进行了更详细的讨论。${parameter…something_else}
关于行情的说明
请注意,您应该始终引用 shell 变量,除非您有充分的理由不这样做,并且您确定自己知道自己在做什么。相比之下,虽然大括号很重要,但它们不如引号重要。
$ filename="童谣.txt" $ ls -ld ${文件名} ls:无法访问托儿所:没有这样的文件或目录 ls: 无法访问 rhyme.txt: 没有那个文件或目录 $ ls -ld "$文件名" -rwxr-xr-x 1 Noob Noob 5309 Jul 2 11:09 童谣.txt
这也适用于位置参数(即命令行参数;例如,"$1"
)以及命令替换:
$ ls -ld $(date "+%B %Y").txt ls: 无法访问 七月: 没有那个文件或目录 ls: 无法访问 2015.txt: 没有那个文件或目录 $ ls -ld "$(date "+%B %Y").txt" -rwxr-xr-x 1 Noob Noob 687 Jul 2 11:09 July 2015.txt
请参阅Bash 引号在命令替换时未转义,以
获取有关引号和$(
...之间交互的简短论文)
。
在您的示例中, $var 和 ${var} 是相同的。但是,当您希望在字符串中扩展变量时,大括号很有用:
$ string=foo
$ echo ${string}bar
foobar
$ echo $stringbar
$
Run Code Online (Sandbox Code Playgroud)
因此,大括号提供了一种替换变量的方法,以便获得要替换的新变量的名称。
我通常在字符串中更常见到它。像这样的事情是行不通的:
var="a"
echo "$varRAW_STRING"
Run Code Online (Sandbox Code Playgroud)
但这会:
var="a"
echo "${var}RAW_STRING"
Run Code Online (Sandbox Code Playgroud)
正如您所说,$()
用于执行命令:
dir_contents=$(ls)
Run Code Online (Sandbox Code Playgroud)
您也可以使用反引号,但我发现反$()
引号更通用。一方面,反引号不能(轻易)嵌套。
date_directory=`ls `date '+%Y-%m-%d'`` # Makes no sense
date_directory=$(ls $(date '+%Y-%m-%d')) # Much better
Run Code Online (Sandbox Code Playgroud)