Menu Close

外壳脚本的特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数

一)特殊变量

变量名只能包含数字、字母和下划线,因为某些包含其他字符的变量有特殊含义,这样的变量被称为特殊变量。

例如,$ 表示当前Shell进程的ID,即pid,看下面的代码:

 echo $$

特殊变量列表
变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $* 稍有不同,下面将会讲到。
$? 上个命令的退出状态,或函数的返回值。
$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

二)命令行参数

2.1) $0 and $n

其中 $0 指向实际的命令、程序、Shell 脚本或函数。

运行脚本时传递给脚本的参数称为命令行参数。命令行参数用 $n 表示,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。命令行参数 $1$2$3、…$9 是位置参数


2.2)$* 和 $@ 的区别

$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(” “)包含时,都以”$1” “$2” … “$n” 的形式输出所有参数。

但是当它们被双引号(” “)包含时,”$*” 会将所有的参数作为一个整体,以”$1 $2 … $n”的形式输出所有参数;”$@” 会将各个参数分开,以”$1″ “$2” … “$n” 的形式输出所有参数。

有两个特殊参数允许一次访问所有命令行参数。$*$@ 在不加引号的情况下行为相同,但在加引号时有所不同。

这两个参数都指定了命令行参数。然而,"$*" 会将整个列表作为一个参数处理,参数之间用空格分隔,而 "$@" 会将整个列表分开成多个独立的参数。

可以编写如下 Shell 脚本来处理未知数量的命令行参数,无论使用 $* 还是 $@ 特殊参数 −

#!/bin/bash

echo "Using \$*:"
for arg in $*
do
  echo "$arg"
done

echo "Using \"\$*\":"
for arg in "$*"
do
  echo "$arg"
done

echo "Using \$@:"
for arg in $@
do
  echo "$arg"
done

echo "Using \"\$@\":"
for arg in "$@"
do
  echo "$arg"
done

运行:

./script_name.sh arg1 "arg2 with spaces" arg3

运行结果:

Using $*:
arg1
arg2
with
spaces
arg3

Using "$*":
arg1 arg2 with spaces arg3

Using $@:
arg1
arg2 with spaces
arg3

Using "$@":
arg1
arg2 with spaces
arg3

在这个示例中:

  • "$*" 将整个参数列表作为一个单一的参数处理,所有参数之间用空格分隔。
  • "$@" 将每个参数单独处理,保留参数中的空格。

使用 "$@" 更适合处理包含空格的参数,因为它会正确保留每个参数的独立性。

2.3 )退出状态

$? 变量表示前一个命令的退出状态。

退出状态是每个命令在完成后返回的数值。通常,大多数命令在成功执行时返回退出状态 0,而在执行失败时返回 1。

一些命令会返回额外的退出状态以表示特定原因。例如,有些命令会区分不同类型的错误,并根据失败的具体类型返回不同的退出值。

下面是一个使用 $? 变量的示例分析,展示如何检查前一个命令的退出状态:

#!/bin/bash

# 运行一个成功的命令
ls / > /dev/null
echo "Exit status after ls: $?"

# 运行一个失败的命令
ls /nonexistent_directory > /dev/null 2>&1
echo "Exit status after ls /nonexistent_directory: $?"

# 运行一个成功的命令
echo "Hello, World!" > /dev/null
echo "Exit status after echo: $?"

# 运行一个失败的命令
cat non_existent_file > /dev/null 2>&1
echo "Exit status after cat non_existent_file: $?"

解释:

  1. ls / 是一个成功的命令,列出根目录的内容。退出状态会是 0,因此 $? 将返回 0。
  2. ls /nonexistent_directory 是一个失败的命令,因为该目录不存在。退出状态将是 2(具体值可能因不同的命令而异),因此 $? 将返回 2。
  3. echo "Hello, World!" 是一个成功的命令,输出文本到标准输出。退出状态将是 0,因此 $? 将返回 0。
  4. cat non_existent_file 是一个失败的命令,因为文件不存在。退出状态将是 1,表示发生了错误。

示例运行结果:

Exit status after ls: 0
Exit status after ls /nonexistent_directory: 2
Exit status after echo: 0
Exit status after cat non_existent_file: 1

这个示例展示了如何使用 $? 来检查和处理不同命令的退出状态,以便在脚本中做出适当的响应。

READ  Python 变量、常量和数字文字, 字符串文字, 布尔文字, 文字集合, 和特殊文字以及变量和常量的规则和命名约定

2.4 $!  – 最后一个后台进程的进程 ID

以下是一个示例,演示如何使用 $! 变量来获取最后一个后台进程的进程 ID(PID):

#!/bin/bash

# 启动一个后台进程
sleep 30 &
# 获取最后一个后台进程的 PID
BACKGROUND_PID=$!

# 输出后台进程的 PID
echo "The PID of the last background process is: $BACKGROUND_PID"

# 等待后台进程完成
wait $BACKGROUND_PID

# 输出后台进程完成后的消息
echo "The background process with PID $BACKGROUND_PID has completed."

解释:

  1. sleep 30 & 启动一个后台进程,该进程会休眠 30 秒。& 符号用于将进程放到后台运行。
  2. BACKGROUND_PID=$! 将最后一个后台进程的 PID 存储在变量 BACKGROUND_PID 中。$! 变量表示最后一个后台进程的 PID。
  3. echo "The PID of the last background process is: $BACKGROUND_PID" 输出后台进程的 PID。
  4. wait $BACKGROUND_PID 等待指定的后台进程完成。
  5. echo "The background process with PID $BACKGROUND_PID has completed." 输出后台进程完成后的消息。

运行

./script_name.sh

运行结果

The PID of the last background process is: 12345
The background process with PID 12345 has completed.

在这个示例中,$! 用于获取并存储最后一个后台进程的进程 ID,以便后续可以使用 wait 命令等待该进程完成。

2.5)总和命令行实例

以下脚本 script_name.sh 使用了与命令行相关的各种特殊变量 −

#!/bin/bash

# 输出脚本名称
echo "Script name: $0"

# 输出第一个、第二个和第三个参数
echo "First argument: $1"
echo "Second argument: $2"
echo "Third argument: $3"

# 输出所有参数
echo "All arguments: $@"

# 输出参数的数量
echo "Number of arguments: $#"

# 显示当前 Shell 的进程 ID
echo "Current Shell PID: $$"

# 显示最后一个命令的退出状态
echo "Exit status of the last command: $?"

# 显示最后一个后台命令的进程 ID
echo "PID of the last background command: $!"

运行:

./script_name.sh arg1 arg2 arg3

运行结果:

Script name: ./script_name.sh
First argument: arg1
Second argument: arg2
Third argument: arg3
All arguments: arg1 arg2 arg3
Number of arguments: 3
Current Shell PID: 12345
Exit status of the last command: 0
PID of the last background command: 6789

在这个示例中,脚本使用了多个特殊变量来输出脚本名称、传递的参数、参数的数量,以及其他相关信息。

 

结论:特殊字符的应用:

$0当前脚本的文件名

$n传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。

$#传递给脚本或函数的参数个数。

$*传递给脚本或函数的所有参数。

$@传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $* 稍有不同。

$?上个命令的退出状态,或函数的返回值。

$$当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

 

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Leave the field below empty!

Posted in 外壳脚本

Related Posts