变量与用户输入

ShellBeginner
立即练习

简介

想象一下你有一个机器人服务员。静态机器人只能对每个人说「你好,先生」。动态机器人则可以询问你的名字,然后说「你好,Sarah」或「你好,Mike」。

在上一个实验中,你的脚本每次都执行完全相同的操作。在本实验中,你将让数据从脚本外部传入,从而使脚本变得动态。

这是编程中的一个重大转变。脚本能够接收输入后,就不再只是固定的演示程序,而会成为可重复使用的工具。

你将学习两种与脚本交互的方式:

  1. 询问并等待:脚本暂停并向你提问(使用 read)。
  2. 传入信息:启动脚本时直接向它传入信息(使用参数)。

完成本实验后,你的代码就可以向任何你想要的人打招呼,而不只是向「World」打招呼。

使用 read 接收交互式输入

第一种方法是「对话式」方法。我们让脚本打印一个问题,然后等待回答。

我们将使用 read 命令。可以把 read 理解为这样一句话:「暂停所有操作,注意听,等待用户输入内容。」

这是你第一次学习脚本在运行过程中接收数据。在 Shell 脚本中,变量是一个用于临时存储数据的命名位置,例如用户名、文件名或数字。变量可以让脚本重复使用,因为脚本能够处理不断变化的输入,而不是只能使用硬编码文本。

首先,确认你位于项目工作区:

cd ~/project

使用 nano 创建名为 hello.sh 的新文件:

nano hello.sh

输入以下代码。 注意:我们定义了一个名为 name 的「盒子」(变量),用于存储用户的回答。

#!/bin/bash

echo "What is your name?"
read name
echo "Hello, $name!"

下面逐项说明:

  • echo "...":脚本向你说话。
  • read name:脚本等待输入。你输入的内容会被放入 name 这个盒子中。
  • $name:脚本打开这个盒子。$ 符号是访问变量内容的关键。

注意 name 和 $name 的区别。创建或填充变量时,name 是变量的名称;$name 表示「用变量中存储的值替换这里」。这种替换称为展开(expansion),是 Shell 最重要的行为之一。

保存文件(按 Ctrl+O,再按回车键)并退出(按 Ctrl+X)。

运行交互式脚本

在与脚本交互之前,必须先授予它运行权限。还记得上一个实验中的「钥匙」吗?

授予执行权限:

chmod +x hello.sh

现在开始与脚本对话。运行脚本:

./hello.sh

脚本会询问「What is your name?」,然后暂停。它正在等待你的输入,光标可能会闪烁。

输入你的名字(例如 Alice),然后按回车键。

What is your name?
Alice
Hello, Alice!

这称为交互式输入。对于有人操作的工具来说,它非常方便,但不适合自动化。想象一下,尝试在凌晨 3 点自动运行这个脚本。由于一直等不到回答,脚本会卡住!

这种取舍在实际运维工作中非常重要。有人在场时,交互式脚本很方便;但计划任务、CI 流水线和启动脚本通常需要非交互式输入,这样才能在无人值守的情况下运行。

使用参数接收非交互式输入

为了让脚本适合自动化,我们需要在脚本运行之前把数据传给它,这样脚本就不需要暂停。我们可以使用参数来实现这一点。

可以把参数想象成门上的「投信口」。你经过门口时,把信息投进去即可。

在 Bash 中,这些投信口使用编号命名:

  • $1 表示脚本名称后输入的第一个单词。
  • $2 表示第二个单词,以此类推。

这些编号值称为位置参数。脚本启动时,Shell 会自动创建它们。你不需要自行定义 $1;Bash 会根据启动脚本的命令行内容为它赋值。

现在升级 hello.sh,让它读取第一个投信口 $1,而不是提问。

打开文件:

nano hello.sh

将代码修改为:

#!/bin/bash

name=$1
echo "Hello, $name!"

这里,name=$1 会获取 $1 投信口中的内容,并将其放入 name 这个盒子中。没有暂停,也没有问题。

保存并退出。

使用参数运行脚本

现在需要用不同的方式运行脚本。启动脚本时,直接把名字「扔」给它即可。

运行以下命令:

./hello.sh LabEx

这里的 LabEx 就是参数。脚本会将它作为 $1 获取,并立即打印:

Hello, LabEx!

使用另一个名字试试:

./hello.sh World

脚本会立即运行,没有任何暂停。

空投信口问题

如果不提供参数,会发生什么?

./hello.sh

你会得到:

Hello, !

$1 投信口为空,因此 name 这个盒子也是空的。在后续实验中,你将学习如何检测这种情况并显示错误消息;但现在,你已经成功构建了一个简洁、适合自动化的脚本!

交互式输入与命令行参数之间的区别非常基础。read 会在脚本运行期间提问,而 $1 从脚本启动的最开始就可用。许多 Unix 工具都围绕参数设计,因为参数更容易自动化、记录、重复使用,也更容易与其他命令组合。

总结

恭喜你!你已经学会了「倾听的艺术」。

在本实验中,你学习了:

  1. 交互模式:使用 read 与用户对话(适合人操作)。
  2. 参数模式:使用 $1 在脚本启动时接收数据(适合机器人或自动化任务)。

你还了解到,变量(例如 $name)只是脚本用来存储信息的带标签盒子。这个概念是所有编程的基础!