String 为什么我的shell脚本为每种情况提供相同的输出?

String 为什么我的shell脚本为每种情况提供相同的输出?,string,bash,shell,compare,String,Bash,Shell,Compare,问题是编写一个脚本,检查读取的字符是“Y”、“Y”、“n”还是“n”,并相应地显示结果 然而,对于我给出的每一个输入,我得到的输出都是肯定的。我是一个完全的脚本新手,不知道是什么原因造成的 代码如下: #!/bin/bash read CHAR if [ [$CHAR=="Y"] -o [$CHAR=="y"] ]; then echo "YES" elif [ [$CHAR=="N"] -o [$CHAR=="n"] ]; then echo "NO" fi

问题是编写一个脚本,检查读取的字符是“Y”、“Y”、“n”还是“n”,并相应地显示结果

然而,对于我给出的每一个输入,我得到的输出都是肯定的。我是一个完全的脚本新手,不知道是什么原因造成的

代码如下:

#!/bin/bash
read CHAR

if [ [$CHAR=="Y"] -o [$CHAR=="y"] ]; then
        echo "YES"
elif [ [$CHAR=="N"] -o [$CHAR=="n"] ]; then
        echo "NO"
fi

括号与
test
表达式中的括号不同。另外,
test
使用
=
,而不是
=
。您还需要将to表达式正确地拆分为标记(通过在
=
符号周围添加空格)。因此,你想要的是:

if [ "$CHAR" = Y -o "$CHAR" = y ]; then
    echo "YES"
elif [ "$CHAR" = N -o "$CHAR" = n ]; then
    echo "NO"
fi
注意,我还引用了
“$CHAR”
。这使得程序在
$CHAR
为空或包含空格的情况下更加健壮。另一方面,
Y
N
不需要任何引用,因为它们是常量,不包含空格


更准确地说,当每个
$CHAR
表达式扩展为一个类似
[N==Y]
的标记时,程序中会发生什么,这是一个对
测试没有特殊意义的标记。任何缺乏特殊意义的标记都会被
test
解释为“true”。

您需要使用单个
=
进行字符串比较,并且括号太多。因此,代码变成:

#!/bin/bash
read CHAR

if [ "$CHAR" = "Y" -o "$CHAR" = "y" ]; then
  echo "YES"
elif [ "$CHAR" = "N" -o "$CHAR"="n" ]; then
  echo "NO"
fi
下次当您想调试脚本为什么不工作时,请按如下方式运行:
bash-x./script.sh
或在
bash
之后的第一行中添加
-x


检查以下一个衬里:

read CHAR && [ "${CHAR^^}" = "Y" ] && echo YES || echo NO
它正在使用,请参阅:

试试这个!
问题似乎是带双“=”的“-o”的用法,以及if和elif中的空格作为括号。

case语句可能非常可读

read char
case ${char,} in
  y*) echo Yes;;
  n*) echo No;;
esac

谢谢!!成功了。但是你能解释一下脚本中正确间隔的重要性吗?我还没有弄明白,它只是更干净,更容易阅读,更接近通用的编码标准,所以这是一个很好的实践。其次,如果表达式之间没有空格(
[
]
),bash有时会失败。这是因为
[
不是shell语法。它是一个命令(例如,请参见
ls/usr/bin[
),因此它需要是自己的单词才能正常工作。你不会期望
echo“$CHAR”
要工作,请避免使用
所有的大写变量。按照惯例,它们是为shell/etc保留的。bash 4+仅用于较低的外壳扩展。
read char
case ${char,} in
  y*) echo Yes;;
  n*) echo No;;
esac