20. Bash 特殊参数


下表解释了 bash 各种特殊参数

特殊参数 描述
$* 包含所有的位置参数
$@ 和上面一样,包含所有的位置参数
$# 位置参数的总数量。 即传递给 shell 脚本的参数总数
$$ 包含 shell 的 PID
$! 包含最近执行的后台进程的 PID
$? 包含最近执行的命令的退出状态。
$- 包含使用 bash set 内置命令设置的所有选项。
$_ 给出前一个命令的最后一个参数。 在 shell 启动时,它给出正在执行的 shell 脚本的绝对文件名。

$#是特殊参数,它给出位置参数的总数。 在 shell 脚本的开头使用它可以确保用户将所需的参数传递给 shell 脚本,并在用户未提供所需数量的参数时显示 Usage 消息。

$ cat args-count.sh
#!/bin/bash
if [ $# -lt 2 ]
then
    echo "Usage: $0 arg1 arg2"
    exit
fi
echo -e "\$1=$1"
echo -e "\$2=$2"
let add=$1+$2
let sub=$1-$2
let mul=$1*$2
let div=$1/$2
echo -e "Addition=$add\nSubtraction=$sub\nMultiplication=$mul\nDivision=$div\n"

如果传递给脚本的参数总数小于 2,它将抛出如下所示的使用信息

$ ./args-count.sh 10
Usage: ./args-count.sh arg1 arg2

在 shell 脚本中,您可能想要创建一些临时文件或目录来执行一些操作。 您可以创建 temp[PID].log,而不是创建tmp.log文件,其中 PID 是为执行 shell 脚本而生成的 bash shell 的进程。 当您希望在多次执行 shell 脚本的同时创建一个需要唯一性的临时文件(或目录)时,这很有帮助。

以下脚本在 /tmp 下创建临时日志文件和目录。

$ cat create-temp.sh
echo "Temporary file = /tmp/temp$$.log"
touch /tmp/temp$$.log
echo "Temporary directory = /tmp/temp.$$"
mkdir /tmp/temp.$$

$ ./create-temp.sh
Temporary file = /tmp/temp17134.log
Temporary directory = /tmp/temp.17134

执行shell脚本后,您将看到临时文件和目录:

$ ls -l /tmp/
drwxr-xr-x. 2 ramesh 4096 Aug 6 23:30 temp.17134/
-rw-r--r--. 1 ramesh 0 Aug 6 23:30 temp17134.log

如果您在 shell 脚本内创建仅在 shell 脚本内需要的临时文件或目录,请确保在 shell 脚本末尾将其删除:

rm /tmp/temp$$.log
rm -rf /tmp/temp.$$

$ cat special-params.sh
#!/bin/bash
echo "1. [\$_] = $_"
/usr/local/bin/dbhome 2> /dev/null
if [ "$?" -ne "0" ]; then
    echo "2. Previous command execution failed! Checked
    using [\$?] "
fi
echo "3. [\$-] = $-"
touch /tmp/test.$$
cp /tmp/test.$$ /tmp/test.log
echo "4. [\$_] = $_"
rm /tmp/test.$$ /tmp/test.log

现在,执行上面的脚本。

$ ./special-params.sh
1. [$_] = ./special-params.sh
2. Previous command execution failed! Checked using [$?]
3. [$-] = hB
4. [$_] = /tmp/test.log

  • $_ 位于脚本开头,显示用于执行脚本的文件的绝对名称。
  • $? 用于检查前一条命令是否执行成功。 在这种情况下,命令 /usr/local/bin/dbhome 不存在,因此$?返回 1。
  • $- 显示之前使用 set命令设置的选项。
  • $_ 用于脚本中的其他任何地方(除了开头)给出了前一个命令的最后一个参数的值。 在此示例中,前面的命令是cp /tmp/test.$$ /tmp/test.log。 因此该命令中的最后一个参数是/tmp/test.log