介绍
在本实验中,你将学习 Shell 脚本中的特殊变量。这些变量提供了关于脚本执行环境的关键信息,例如命令行参数、脚本名称和进程 ID。掌握这些变量将帮助你编写更加灵活且功能强大的 Shell 脚本。
在本实验中,你将学习 Shell 脚本中的特殊变量。这些变量提供了关于脚本执行环境的关键信息,例如命令行参数、脚本名称和进程 ID。掌握这些变量将帮助你编写更加灵活且功能强大的 Shell 脚本。
让我们从创建一个简单的 Shell 脚本开始,以此来演示特殊变量的使用。
在 WebIDE 中打开终端。你应该能看到一个等待输入的命令行提示符。
切换到项目目录:
cd ~/project
此命令将当前目录更改为 ~/project,这是你本实验的默认工作目录。
special_vars.sh 的新文件:touch special_vars.sh
touch 命令会在文件不存在时创建一个空文件,如果文件已存在则更新其时间戳。
在 WebIDE 编辑器中打开该文件。你可以通过点击屏幕左侧文件浏览器中的文件名来完成此操作。
将以下内容添加到文件中:
#!/bin/bash
echo "Script Name: $0"
echo "First Argument: $1"
echo "Second Argument: $2"
echo "All Arguments: $@"
echo "Number of Arguments: $#"
echo "Process ID: $$"
让我们逐行解析每一项的作用:
#!/bin/bash:这被称为 Shebang。它告诉系统使用 bash 来解释执行此脚本。$0:这个特殊变量保存了脚本的名称。$1 和 $2:分别代表第一个和第二个命令行参数。$@:代表传递给脚本的所有命令行参数。$#:提供命令行参数的总数。$$:提供当前 Shell 的进程 ID(PID)。添加内容后保存文件。
在终端运行以下命令,为脚本添加执行权限:
chmod +x special_vars.sh
chmod 命令用于更改文件权限。+x 选项增加了执行权限,允许你运行该脚本。
现在我们已经创建了脚本,让我们带上不同的参数来运行它,看看特殊变量是如何表现的。
./special_vars.sh
脚本名称前的 ./ 告诉 Shell 在当前目录中查找该脚本。
你应该会看到类似这样的输出:
Script Name: ./special_vars.sh
First Argument:
Second Argument:
All Arguments:
Number of Arguments: 0
Process ID: 1234
请注意,由于我们没有提供任何参数,第一个和第二个参数为空,且参数个数为 0。
./special_vars.sh hello world
输出应该如下所示:
Script Name: ./special_vars.sh
First Argument: hello
Second Argument: world
All Arguments: hello world
Number of Arguments: 2
Process ID: 1235
以下是发生的变化:
$1 现在包含「hello」$2 现在包含「world」$@ 显示了所有参数:「hello world」$# 显示为 2,因为我们提供了两个参数进程 ID($$)在每次运行脚本时可能会有所不同,因为它是由操作系统动态分配的。
$? 和 $!另外两个重要的特殊变量是 $? 和 $!。让我们创建一个新脚本来演示它们的用法。
exit_status.sh 的新文件:touch ~/project/exit_status.sh
#!/bin/bash
echo "Running a successful command:"
ls /home
echo "Exit status: $?"
echo "Running a command that will fail:"
ls /nonexistent_directory
echo "Exit status: $?"
echo "Running a background process:"
sleep 2 &
echo "Process ID of last background command: $!"
让我们解析一下这个脚本:
$? 提供上一个执行命令的退出状态(Exit Status)。0 通常表示成功,而非零值则表示各种错误情况。$! 提供上一个后台命令的进程 ID。& 符号使其在后台运行。chmod +x ~/project/exit_status.sh
./exit_status.sh
你应该会看到类似这样的输出:
Running a successful command:
labex
Exit status: 0
Running a command that will fail:
ls: cannot access '/nonexistent_directory': No such file or directory
Exit status: 2
Running a background process:
Process ID of last background command: 1236
请注意:
ls 命令执行成功,因此 $? 为 0。ls 命令失败(因为目录不存在),因此 $? 为 2(一个表示错误的非零值)。sleep 命令在后台运行,$! 给出了它的进程 ID。特殊变量也可以在函数内部使用。让我们创建一个脚本来演示这一点。
function_vars.sh 的新文件:touch ~/project/function_vars.sh
#!/bin/bash
function print_args {
echo "Function Name: $0"
echo "First Argument: $1"
echo "Second Argument: $2"
echo "All Arguments: $@"
echo "Number of Arguments: $#"
}
echo "Calling function with two arguments:"
print_args hello world
echo "Calling function with four arguments:"
print_args one two three four
这个脚本定义了一个使用特殊变量的函数 print_args。然后,它使用不同数量的参数两次调用该函数。
chmod +x ~/project/function_vars.sh
./function_vars.sh
你应该会看到类似这样的输出:
Calling function with two arguments:
Function Name: ./function_vars.sh
First Argument: hello
Second Argument: world
All Arguments: hello world
Number of Arguments: 2
Calling function with four arguments:
Function Name: ./function_vars.sh
First Argument: one
Second Argument: two
All Arguments: one two three four
Number of Arguments: 4
请注意:
$0 仍然指向脚本名称,而不是函数名称。$1、$2、$@ 和 $# 在函数参数中的作用与在脚本参数中完全一致。特殊变量 $@ 和 $* 都用于表示所有命令行参数,但当它们被包含在双引号中时,行为会有所不同。让我们创建一个脚本来演示这种区别。
at_vs_star.sh 的新文件:touch ~/project/at_vs_star.sh
#!/bin/bash
echo "Using \$@:"
for arg in "$@"; do
echo "Argument: $arg"
done
echo "Using \$*:"
for arg in "$*"; do
echo "Argument: $arg"
done
这个脚本演示了在循环中使用 "$@" 和 "$*" 的区别。
chmod +x ~/project/at_vs_star.sh
./at_vs_star.sh "arg with spaces" another_arg "third arg"
你应该会看到类似这样的输出:
Using $@:
Argument: arg with spaces
Argument: another_arg
Argument: third arg
Using $*:
Argument: arg with spaces another_arg third arg
以下是发生的情况:
"$@" 时,每个参数都被视为一个独立的实体。带有空格的参数会被保留为单个单元。"$*" 时,所有参数都被合并成一个单一的字符串,由 IFS(内部字段分隔符)变量的第一个字符(通常是空格)分隔。当你需要处理可能包含空格或其他特殊字符的参数时,这种区别至关重要。
在本实验中,你学习了 Shell 脚本中的特殊变量以及如何有效地使用它们。你创建了多个脚本来演示各种特殊变量的用法,例如 $0、$1、$@、$#、$$、$? 和 $!。你还探索了这些变量在不同上下文中的表现,包括在函数内部以及处理命令行参数时。
关键要点:
$0、$1、$2 等代表脚本名称和命令行参数。$@ 和 $# 允许你处理所有参数并统计其数量。$$ 提供了当前进程 ID,这在创建唯一的临时文件时非常有用。$? 帮助你检查上一个命令是否执行成功。$! 提供了上一个后台进程的 PID,在作业控制中非常有用。"$@" 和 "$*" 在加引号时表现不同,这在处理带空格的参数时非常重要。理解这些特殊变量对于编写更高级、更灵活的 Shell 脚本至关重要。它们允许你创建能够适应不同输入并提供执行环境重要信息的脚本。
随着你继续练习和尝试 Shell 脚本,你会发现更多在工作中使用这些特殊变量的方法。记得查阅 Bash 手册(man bash)以获取有关这些变量及其他特殊变量的更详细信息。