如何在 Bash 中使用变量

如果您想编写脚本并了解您将从网络上剪切和粘贴的代码将对您的 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

这一次,fo​​lder_to_count 变量被赋予了第一个命令行参数 $1 的值。

脚本的其余部分与以前完全相同。 您的脚本现在不是一个特定的解决方案,而是一个通用的解决方案。 您可以在任何目录上使用它,因为它没有硬编码为只能与“/dev”一起使用。

以下是使脚本可执行的方法:

chmod +x fcnt2.sh

现在,尝试使用几个目录。 您可以先执行“/dev”以确保获得与以前相同的结果。 键入以下内容:

./fnct2.sh /dev
./fnct2.sh /etc
./fnct2.sh /bin

对于“/dev”目录,您会得到与以前相同的结果(207 个文件)。 这是令人鼓舞的,您可以获得其他每个命令行参数的特定于目录的结果。

  如何更改 Microsoft Teams 头像

为了缩短脚本,您可以完全省去变量 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 可以轻松访问,例如您的用户名、语言环境、历史文件可以保存的命令数量、默认编辑器等等。

  如何在 Microsoft Word 中更改纸张大小

要查看 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。 这样,您可以确保将要发生的事情是您想要的。 您还可以发现您在语法中可能犯的任何错误。