跳转到内容

Bash Shell 脚本/变量

来自维基教科书,开放的书籍,为开放的世界

在 Bash 脚本中,有几种不同类型的参数可以保存。一种主要类型的参数是变量:命名的参数。如果您熟悉任何其他命令式编程语言(例如 C、BASIC、Fortran 或 Pascal),那么您已经熟悉变量。以下简单脚本使用变量location保存值world,并输出“Hello, world!”消息

location=world               # store "world" in the variable "location"
echo "Hello, ${location}!"   # print "Hello, world!"

如您所见,第二行中的字符串${location}在运行该命令之前被替换为world。这种替换被称为变量扩展

注意

此处空格的缺失很重要!命令location = worldlocation= worldlocation =world将无法正常工作。例如,对于location = world,它将尝试使用参数=world运行命令location

变量扩展比您想象的更灵活。例如,它甚至可以保存要运行的命令的名称

cmd_to_run=echo                   # store "echo" in the variable "cmd_to_run"
"${cmd_to_run}" 'Hello, world!'   # print "Hello, world!"

在以上两个示例中,我们都使用了${variable_name}表示法来执行变量扩展。更简短的表示法$variable_name(不带花括号)在这些情况下将具有相同的效果。有时需要花括号(例如,${foo}bar不能写成$foobar,因为后者将被解释为${foobar}),但通常可以省略它们,并且现实世界的脚本通常省略它们。

当然,不必说,以上并不是非常现实的例子;它们只演示了如何使用变量,而不是为什么何时使用它们。如果您熟悉其他命令式编程语言,那么您可能已经清楚地知道为什么以及何时使用变量;如果不是,那么当您阅读本书并看到更现实地使用它们的示例时,这一点应该会变得清晰。

您可能已经注意到,对于包含变量扩展的字符串,我们使用了双引号",而不是单引号'。这是因为单引号会阻止变量扩展;类似echo '${location}'的命令将打印实际字符串${location},而不是打印名为location的变量的值。

通常建议将变量扩展括在双引号中,因为否则变量扩展的结果将经过文件名扩展,以及单词分割(通过空格来分隔构成命令的单词)。例如,此脚本

foo='a  b*'    # store "a  b*" in the variable "foo"
echo $foo

可能打印类似a ba.txt bd.sh的内容,这可能不是我们想要的。现实世界的脚本通常不包含双引号,除非它们是明确必要的,但这种做法有时会导致令人困惑的错误。

提示

通常建议将变量扩展括在双引号中;例如,使用"$var"而不是$var

许多变量具有特殊的意义。例如,变量PATH决定了 Bash 在尝试运行外部程序时应该搜索的目录列表;如果它设置为/usr/bin:/bin,那么命令cp src.txt dst.txt将尝试运行/usr/bin/cp/bin/cp。变量HOME预先初始化为当前用户的 home 目录,它决定了波浪号扩展的行为。例如,如果一个脚本设置了HOME=/foo,那么echo ~/bar将打印/foo/bar。(但是,这并不会真正改变用户的 home 目录。)

华夏公益教科书