Bash 语法问题中的 If 语句产生正确的答案,而正确的代码显示错误的答案

If-statements in Bash Syntax issues produce right answers, while right code shows wrong answers

我对 bash 脚本编写相当陌生,并且正在为一些 if 语句语法而苦苦挣扎。

我目前已经编写了以下循环:

for (( i = 2; i < $# - 1; i++)); do
    if [ $i -ne 0]; then
        if [ $i -ne 1]; then
            echo "$i was not 1 or 0. Please correct this then try again."
            exit 1;
        fi
    fi
done

这段代码应该测试第一个参数之后的参数是 1 还是 0。

同时打印出以下错误:

./blink.sh: line 36: [: missing `]'
./blink.sh: line 36: [: missing `]'

...之后代码实际上运行良好(因此错误不会终止程序)。

然而,我的理解是,在 bash 中,您在 if 语句中的表达式前后放置了空格。所以这个:

if [ $i -ne 0]; then

变为:

if [ $i -ne 0 ]; then

但是,运行 此代码生成以下内容:

2 was not 1 or 0. Please correct this then try again.

我遇到的主要问题是不理解如何间接引用执行命令提供的位置参数。因此,我很困惑必须更改什么语法才能调用参数指向的对象(在这种情况下,希望是 1 或 0)而不是参数本身的位置(参数 1、2、3。 ..).

谢谢!

编辑: 更改问题以更好地适应@randomir 提供的建议并弄清实际问题的含义

基于:

This code is supposed to test whether any arguments after the first are either a 1 or a 0.

我假设您正在尝试访问位置参数 </code>、<code> 等。要使 for 循环解决方案有效,您必须使用 indirect reference: ${!i} (see shell parameter expansion).例如,这应该有效:

#!/bin/bash
for (( i = 2; i <= $#; i++ )); do
    if [[ ${!i} -ne 0 ]]; then
        if [[ ${!i} -ne 1 ]]; then
            echo "$i was not 1 or 0. Please correct this then try again."
            exit 1;
        fi
    fi
done

注意 i 运行 从 2 到参数数量 $#。另外,请注意使用推荐的且不易出错的 [[ .. ]] 而不是 [ .. ](否则您将不得不编写 [ "${!i}" -ne 0 ] 等)。

避免不必要的间接引用的更简单的解决方案如下所示:

#!/bin/bash
while [[  ]]; do
    if ((  != 0 &&  != 1 )); then
        echo " is neither 0, nor 1"
        exit 1
    fi
    shift
done

我们开始检查第二个参数(</code>),使用算术表达式<code>(( expr ))测试第二个参数的值,并且shift位置参数向左移动1处每次迭代(现在 </code> 变为 <code>,等等)。