执行我的 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 被回显。

yY 在此上下文中被视为 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