如果您想编写脚本并了解您将从网络上剪切和粘贴的代码将对您的 Linux 计算机产生什么影响,那么变量是至关重要的。 我们会让你开始!
目录
变量 101
变量是表示字符串或数值的命名符号。 当您在命令和表达式中使用它们时,它们被视为您输入了它们所保存的值而不是变量的名称。
要创建变量,您只需为其提供名称和值。 您的变量名称应该是描述性的,并提醒您它们所持有的值。 变量名不能以数字开头,也不能包含空格。 但是,它可以以下划线开头。 除此之外,您可以使用任何大小写字母数字字符的组合。
例子
在这里,我们将创建五个变量。 格式是键入名称、等号 = 和值。 请注意,等号前后没有空格。 给变量一个值通常被称为为变量赋值。
我们将创建四个字符串变量和一个数字变量 this_year:
me=Dave
my_boost=Linux
him=Popeye
his_boost=Spinach
this_year=2019
到 看价值 保存在变量中,使用 echo 命令。 每当您引用它包含的值时,您必须在变量名称前面加上一个美元符号 $,如下所示:
echo $my_name
echo $my_boost
echo $this_year
让我们一次使用所有变量:
echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"
变量的值替换它们的名称。 您还可以更改变量的值。 要为变量 my_boost 分配新值,只需重复分配第一个值时所做的操作,如下所示:
my_boost=Tequila
如果您重新运行之前的命令,您现在会得到不同的结果:
echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"
因此,如果您更改变量中保存的值,您可以使用引用相同变量的相同命令并获得不同的结果。
稍后我们将讨论引用变量。 现在,这里有一些事情要记住:
单引号 ‘ 中的变量被视为文字字符串,而不是变量。
引号中的变量“被视为变量。
要获取变量中保存的值,您必须提供美元符号 $。
没有美元符号 $ 的变量仅提供变量的名称。
您还可以创建一个从现有变量或多个变量中获取其值的变量。 以下命令定义了一个名为 drink_of_the_Year 的新变量,并将 my_boost 和 this_year 变量的组合值分配给它:
drink_of-the_Year="$my_boost $this_year"
echo drink_of_the-Year
如何在脚本中使用变量
如果没有变量,脚本将完全瘫痪。 变量提供了使脚本成为通用解决方案而非特定解决方案的灵活性。 为了说明差异,这里有一个计算 /dev 目录中文件的脚本。
将其输入文本文件,然后将其保存为 fcnt.sh(用于“文件计数”):
#!/bin/bash folder_to_count=/dev file_count=$(ls $folder_to_count | wc -l) echo $file_count files in $folder_to_count
在运行脚本之前,您必须使其可执行,如下所示:
chmod +x fcnt.sh
键入以下内容以运行脚本:
./fcnt.sh
这将打印 /dev 目录中的文件数。 以下是它的工作原理:
定义了一个名为 folder_to_count 的变量,并将其设置为保存字符串“/dev”。
定义了另一个名为 file_count 的变量。 此变量从命令替换中获取其值。 这是括号 $( ) 之间的命令短语。 请注意,第一个括号之前有一个美元符号 $。 这个构造 $( ) 计算括号内的命令,然后返回它们的最终值。 在此示例中,该值被分配给 file_count 变量。 就 file_count 变量而言,它传递了一个值来保存; 它不关心如何获得价值。
在命令替换中评估的命令在 folder_to_count 变量中的目录上执行 ls 文件列表,该变量已设置为“/dev”。 因此,脚本执行命令“ls /dev”。
此命令的输出通过管道传送到 wc 命令。 -l(行数)选项使 wc 计算行数 在 ls 命令的输出中。 由于每个文件都列在单独的行上,因此这是“/dev”目录中文件和子目录的计数。 该值分配给 file_count 变量。
最后一行使用 echo 输出结果。
但这仅适用于“/dev”目录。 我们如何使脚本适用于任何目录? 所需要的只是一个小小的改变。
如何在脚本中使用命令行参数
许多命令,例如 ls 和 wc,采用命令行参数。 这些为命令提供信息,因此它知道您想要它做什么。 如果您希望 ls 在您的主目录上工作并且 也显示隐藏文件,您可以使用以下命令,其中波浪号 ~ 和 -a(全部)选项是命令行参数:
ls ~ -a
我们的脚本可以接受命令行参数。 第一个参数引用为 $1,第二个参数引用为 $2,依此类推,第九个参数引用为 $9。 (实际上,还有 0 美元,但它是为始终保存脚本而保留的。)
您可以像引用常规变量一样在脚本中引用命令行参数。 让我们修改我们的脚本,如下所示,并用新名称 fcnt2.sh 保存它:
#!/bin/bash folder_to_count=$1 file_count=$(ls $folder_to_count | wc -l) echo $file_count files in $folder_to_count
这一次,folder_to_count 变量被赋予了第一个命令行参数 $1 的值。
脚本的其余部分与以前完全相同。 您的脚本现在不是一个特定的解决方案,而是一个通用的解决方案。 您可以在任何目录上使用它,因为它没有硬编码为只能与“/dev”一起使用。
以下是使脚本可执行的方法:
chmod +x fcnt2.sh
现在,尝试使用几个目录。 您可以先执行“/dev”以确保获得与以前相同的结果。 键入以下内容:
./fnct2.sh /dev
./fnct2.sh /etc
./fnct2.sh /bin
对于“/dev”目录,您会得到与以前相同的结果(207 个文件)。 这是令人鼓舞的,您可以获得其他每个命令行参数的特定于目录的结果。
为了缩短脚本,您可以完全省去变量 folder_to_count,而只在整个过程中引用 $1,如下所示:
#!/bin/bash file_count=$(ls $1 wc -l) echo $file_count files in $1
使用特殊变量
我们提到了 $0,它总是设置为脚本的文件名。 这允许您使用脚本来执行诸如正确打印其名称之类的操作,即使它已重命名。 这在记录情况下很有用,在这种情况下,您想知道添加条目的进程的名称。
以下是其他特殊预设变量:
$#:传递给脚本的命令行参数的数量。
[email protected]:传递给脚本的所有命令行参数。
$?: 最后运行的进程的退出状态。
$$:当前脚本的进程 ID (PID)。
$USER:执行脚本的用户的用户名。
$HOSTNAME:运行脚本的计算机的主机名。
$SECONDS:脚本运行的秒数。
$RANDOM:返回一个随机数。
$LINENO:返回脚本的当前行号。
你想在一个脚本中看到所有这些,不是吗? 你可以! 将以下内容另存为名为 special.sh 的文本文件:
#!/bin/bash echo "There were $# command line parameters" echo "They are: [email protected]" echo "Parameter 1 is: $1" echo "The script is called: $0" # any old process so that we can report on the exit status pwd echo "pwd returned $?" echo "This script has Process ID $$" echo "The script was started by $USER" echo "It is running on $HOSTNAME" sleep 3 echo "It has been running for $SECONDS seconds" echo "Random number: $RANDOM" echo "This is line number $LINENO of the script"
键入以下内容以使其可执行:
chmod +x special.sh
现在,您可以使用一堆不同的命令行参数运行它,如下所示。
环境变量
Bash 使用环境变量来定义和记录它在启动时创建的环境的属性。 这些保存信息 Bash 可以轻松访问,例如您的用户名、语言环境、历史文件可以保存的命令数量、默认编辑器等等。
要查看 Bash 会话中的活动环境变量,请使用以下命令:
env | less
如果您滚动浏览列表,您可能会发现一些对您的脚本有用的参考。
如何导出变量
当脚本运行时,它在自己的进程中,并且它使用的变量在该进程之外是看不到的。 如果您想与您的脚本启动的另一个脚本共享一个变量,您必须导出该变量。 我们将通过两个脚本向您展示如何做到这一点。
首先,使用文件名 script_one.sh 保存以下内容:
#!/bin/bash first_var=alpha second_var=bravo # check their values echo "$0: first_var=$first_var, second_var=$second_var" export first_var export second_var ./script_two.sh # check their values again echo "$0: first_var=$first_var, second_var=$second_var"
这将创建两个变量,first_var 和 second_var,并分配一些值。 它将这些打印到终端窗口,导出变量,然后调用 script_two.sh。 当 script_two.sh 终止并且流程返回到该脚本时,它再次将变量打印到终端窗口。 然后,您可以查看它们是否发生了变化。
我们将使用的第二个脚本是 script_two.sh。 这是 script_one.sh 调用的脚本。 键入以下内容:
#!/bin/bash # check their values echo "$0: first_var=$first_var, second_var=$second_var" # set new values first_var=charlie second_var=delta # check their values again echo "$0: first_var=$first_var, second_var=$second_var"
第二个脚本打印两个变量的值,为它们分配新值,然后再次打印它们。
要运行这些脚本,您必须键入以下内容以使其可执行:
chmod +x script_one.sh chmod +x script_two.sh
现在,键入以下内容以启动 script_one.sh:
./script_one.sh
这就是输出告诉我们的:
script_one.sh 打印变量的值,它们是 alpha 和 bravo。
script_two.sh 在收到变量(alpha 和 bravo)时打印它们的值。
script_two.sh 将它们更改为 charlie 和 delta。
script_one.sh 打印变量的值,它们仍然是 alpha 和 bravo。
第二个脚本中发生的事情保留在第二个脚本中。 这就像变量的副本被发送到第二个脚本,但是当该脚本退出时它们被丢弃。 第一个脚本中的原始变量不会被第二个脚本中的副本发生任何改变。
如何引用变量
您可能已经注意到,当脚本引用变量时,它们是用引号“. 这允许正确引用变量,因此在脚本中执行该行时会使用它们的值。
如果您分配给变量的值包含空格,则在您将它们分配给变量时必须将它们放在引号中。 这是因为默认情况下,Bash 使用空格作为分隔符。
这是一个例子:
site_name=How-To Geek
Bash 将“Geek”之前的空格视为新命令正在启动的指示。 它报告没有这样的命令,并放弃该行。 echo 向我们展示了 site_name 变量不包含任何内容——甚至是“How-To”文本。
再试一次,用引号括住值,如下所示:
site_name="How-To Geek"
这一次,它被识别为单个值并正确分配给 site_name 变量。
回声是你的朋友
习惯命令替换、引用变量以及记住何时包含美元符号可能需要一些时间。
在您按 Enter 并执行一行 Bash 命令之前,请尝试在其前面加上 echo。 这样,您可以确保将要发生的事情是您想要的。 您还可以发现您在语法中可能犯的任何错误。