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>
,等等)。
我对 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>
,等等)。