Contents

在bash脚本中使用命令行参数

1. 简介

我们之前研究过如何将命令行参数 传递给 bash 脚本。在本教程中,我们将了解如何在 bash 脚本中使用这些参数。

2. 处理输入

让我们看看在脚本内部处理传递给 bash 脚本的参数的不同方法。

2.1. 位置参数

传递给脚本的参数按照它们发送的顺序进行处理。参数的索引从一个开始,第一个参数可以在脚本内部使用*$1访问。类似地,可以使用$2 *访问第二个参数,依此类推。位置参数是指使用它们的位置的参数的这种表示。

让我们以以下脚本为例,userReg-positional-parameter.sh,它按顺序打印usernameagefull name  :

echo "Username: $1";
echo "Age: $2";
echo "Full Name: $3";

现在让我们使用三个输入参数运行这个脚本:

sh userReg-positional-parameter.sh john 25 'John Smith'

输出将是:

Username : john
Age: 25
Full Name: John Smith

2.2. 标志

使用标志是向脚本传递输入的常用方法。将输入传递给脚本时,每个参数前都有一个以连字符(-)开头的标志(通常是单个字母)

让我们看一下userReg-flags.sh脚本,它接受三个参数:Username (-u)Age (-a)Full Name (-f)

我们将修改前面的脚本以使用标志而不是依赖位置参数。getopts函数读取输入中的标志,OPTARG引用相应的值:

while getopts u:a:f: flag
do
    case "${flag}" in
        u) username=${OPTARG};;
        a) age=${OPTARG};;
        f) fullname=${OPTARG};;
    esac
done
echo "Username: $username";
echo "Age: $age";
echo "Full Name: $fullname";

让我们使用与之前相同的输入运行此脚本,只是这一次,我们将向输入添加标志:

sh userReg-flags.sh -f 'John Smith' -a 25 -u john

输出与以前相同,但我们改变了用户名全名参数的位置:

Username : john
Age: 25
Full Name: John Smith

在这里,我们使用getopts函数来解析作为输入提供的标志,并使用 case 块将指定的值分配给相应的变量。

2.3. 循环构造

位置参数虽然在许多情况下很方便,但在输入大小未知时无法使用。在这些情况下,使用循环构造会派上用场。 变量$@ 是所有输入参数的数组**。在for循环中使用这个变量,我们可以遍历输入并处理所有传递的参数。

让我们以脚本users-loop.sh 为例,它打印所有作为输入传递的用户名:

i=1;
for user in "$@"
do
    echo "Username - $i: $user";
    i=$((i + 1));
done

现在让我们运行脚本:

sh users-loop.sh john matt bill 'joe wicks' carol

我们将看到我们的输出:

Username - 1: john
Username - 2: matt
Username - 3: bill
Username - 4: joe wicks
Username - 5: carol

在上面的示例中,我们在整个输入参数数组上迭代user变量。此迭代从第一个输入参数john开始,一直运行到最后一个参数carol,即使输入的大小未知。

2.4. 移位运算符

bash 中的移位运算符(语法上是shift n,其中n是要移动的位置数)移动命令行参数的位置。如果未指定, n的默认值为1。

移位运算符使输入的索引从移位的位置开始。换句话说,当此运算符用于数组输入时,位置参数*$1将更改为通过从绑定到位置参数$1的当前参数向右移动n *个位置来达到的参数。

考虑一个确定输入是奇数还是偶数的示例脚本:

sh parityCheck.sh 13 18 27 35 44 52 61 79 93

从上面关于位置参数的讨论中,我们现在知道*$1指的是第一个参数,即 13。对输入 1 ( shift 1 ) 使用移位运算符会导致索引从第二个参数开始。也就是说,$1现在指的是第二个参数 (18)。同样,调用shift 2*将导致索引从第四个参数 (35) 开始。

让我们再看一下上面讨论的用户脚本示例。我们现在将使用 shift 运算符,而不是使用*$@变量并对其进行迭代。$#*变量返回输入大小:

i=1;
j=$#;
while [ $i -le $j ] 
do
    echo "Username - $i: $1";
    i=$((i + 1));
    shift 1;
done

让我们使用与上面相同的输入运行脚本:

sh users-shift-operator.sh john matt bill 'joe wicks' carol

输出将与以前相同:

Username - 1: john
Username - 2: matt
Username - 3: bill
Username - 4: joe wicks
Username - 5: carol

在此示例中,我们将每次迭代中的位置参数移动 1,直到到达输入的末尾。因此,$1每次都指向输入中的下一个元素。