执行我的 bash 脚本文件时显示编译时错误
When executing my bash script file it shows a compile time error
这是我的代码:
#! /bin/bash
read word
if (( $word = "y" || $word = "Y" ))
then
echo "YES"
elif (( $word = "n" || $word = "N" ))
then
echo "NO"
fi
我收到这个错误:
Solution.sh: line 5: ((: y = y || y = Y : attempted assignment to non-variable (error token is "= Y ")
Solution.sh: line 8: ((: y = n || y = N : attempted assignment to non-variable (error token is "= N ")
它会编译成功但是给我运行时间错误
您正在使用(非常)非标准的条件语法。考虑简化的:
#!/bin/bash
word=foo
if (( $word = 0 )) # || $word = "Y" ))
then
echo "YES"
elif (( $word = 6 )) # || $word = "N" ))
then
echo "NO"
fi
echo foo = $foo
从某种意义上说,这是有效的语法,bash 会愉快地解析它,但它肯定不会按照您的预期进行。 if (( $word = 0 ))
不检查 $word
是否等于 0。相反,它将 0 赋值给由 $word
命名的变量(在本例中,它赋值给变量 foo
)并决定该值是否非零。由于 $foo
现在为零,因此执行 elif
部分并将 6 分配给 foo
。 $foo
(6) 的新值是非零的,因此 NO
被回显。
值 y
和 Y
在此上下文中被视为 0,但 ||
在这里是一个布尔运算符,代码 $word = 'y' || $word = 'Y'
被解析为它是 $word = ( 'y' || $word ) = 'Y'
,它错误地尝试分配非变量 'y' || $word
。 (或者它可能正在评估 'y' || $word
并尝试分配变量 0
,这不是一个有效的名称。这感觉更像是一个哲学问题。这是一个解析错误,所以我们可能不应该不要试图说出它“试图”做什么。)错误消息向您展示了这一点,并尽最大努力准确指出错误所在。编写 (( $word = 'y' || ( $word = 'Y') ))
是有效的语法,它会将 0
分配给 foo
,但这肯定不是您想要的语义。相反,您的代码应该只是:
#!/bin/bash
read word
case $word in
y|Y) echo YES;;
n|N) echo NO;;
esac
如果出于某种原因你真的想使用链式 if/else 而不是 case
,你需要的语法是:
#! /bin/bash
read word
if test "$word" = y || test "$word" = Y; then
echo "YES"
elif test "$word" = n || test "$word" = N; then
echo "NO"
fi
您经常会看到 test
写成 [
并带有附加的尾随参数 ]
。我认为这是一种可怕的做法。
另请注意,我已经更改了您的引述。双引号变量插值通常是个好主意,但没有必要引用不包含特殊字符或空格的文字字符串。
您想要 [[ ... ]]
,而不是 ((...))
(用于 算术 表达式)
#!/bin/bash
read word
if [[ $word = "y" || $word = "Y" ]]
then
echo "YES"
elif [[ $word = "n" || $word = "N" ]]
then
echo "NO"
fi
您可以使用模式匹配而不是严格的相等性测试来简化此过程
if [[ $word = [Yy] ]]
then
echo "YES"
elif [[ $word = [Nn] ]]
then
echo "NO"
fi
或使用标准 case
语句
case $word in
[Yy]) echo "YES" ;;
[Nn]) echo "NO" ;;
esac
这是我的代码:
#! /bin/bash
read word
if (( $word = "y" || $word = "Y" ))
then
echo "YES"
elif (( $word = "n" || $word = "N" ))
then
echo "NO"
fi
我收到这个错误:
Solution.sh: line 5: ((: y = y || y = Y : attempted assignment to non-variable (error token is "= Y ") Solution.sh: line 8: ((: y = n || y = N : attempted assignment to non-variable (error token is "= N ")
它会编译成功但是给我运行时间错误
您正在使用(非常)非标准的条件语法。考虑简化的:
#!/bin/bash
word=foo
if (( $word = 0 )) # || $word = "Y" ))
then
echo "YES"
elif (( $word = 6 )) # || $word = "N" ))
then
echo "NO"
fi
echo foo = $foo
从某种意义上说,这是有效的语法,bash 会愉快地解析它,但它肯定不会按照您的预期进行。 if (( $word = 0 ))
不检查 $word
是否等于 0。相反,它将 0 赋值给由 $word
命名的变量(在本例中,它赋值给变量 foo
)并决定该值是否非零。由于 $foo
现在为零,因此执行 elif
部分并将 6 分配给 foo
。 $foo
(6) 的新值是非零的,因此 NO
被回显。
值 y
和 Y
在此上下文中被视为 0,但 ||
在这里是一个布尔运算符,代码 $word = 'y' || $word = 'Y'
被解析为它是 $word = ( 'y' || $word ) = 'Y'
,它错误地尝试分配非变量 'y' || $word
。 (或者它可能正在评估 'y' || $word
并尝试分配变量 0
,这不是一个有效的名称。这感觉更像是一个哲学问题。这是一个解析错误,所以我们可能不应该不要试图说出它“试图”做什么。)错误消息向您展示了这一点,并尽最大努力准确指出错误所在。编写 (( $word = 'y' || ( $word = 'Y') ))
是有效的语法,它会将 0
分配给 foo
,但这肯定不是您想要的语义。相反,您的代码应该只是:
#!/bin/bash
read word
case $word in
y|Y) echo YES;;
n|N) echo NO;;
esac
如果出于某种原因你真的想使用链式 if/else 而不是 case
,你需要的语法是:
#! /bin/bash
read word
if test "$word" = y || test "$word" = Y; then
echo "YES"
elif test "$word" = n || test "$word" = N; then
echo "NO"
fi
您经常会看到 test
写成 [
并带有附加的尾随参数 ]
。我认为这是一种可怕的做法。
另请注意,我已经更改了您的引述。双引号变量插值通常是个好主意,但没有必要引用不包含特殊字符或空格的文字字符串。
您想要 [[ ... ]]
,而不是 ((...))
(用于 算术 表达式)
#!/bin/bash
read word
if [[ $word = "y" || $word = "Y" ]]
then
echo "YES"
elif [[ $word = "n" || $word = "N" ]]
then
echo "NO"
fi
您可以使用模式匹配而不是严格的相等性测试来简化此过程
if [[ $word = [Yy] ]]
then
echo "YES"
elif [[ $word = [Nn] ]]
then
echo "NO"
fi
或使用标准 case
语句
case $word in
[Yy]) echo "YES" ;;
[Nn]) echo "NO" ;;
esac