shell中if和else语句的错误

时间:2010-03-09 16:54:27

标签: bash shell

我刚接触Unix中的编程,并且有一个小问题,我不确定如何解决。我的这个脚本的目的是为用户提供各种选项,使他们想要使用的扫描类型。此扫描会检测具有指定变量的重复文件,具体取决于所选的选项。

我根本无法让它工作,我不确定为什么?

另外,如果可能的话,请您就如何更好地显示选择屏幕向我提供建议。我只粘贴了部分代码,因为我想自己弄清楚其余的目标。

#!/bin/bash
same_name="1"
filesize="2"
md5sum="3"
different_name="4"
echo "The list of choices are, same_name=1, filesize=2, md5sum=3 and different name=4"
echo "Search for files with the:"
read choice 
if [$choice == "$same_name" ];then
find /home/user/OSN -type f -exec basename '{}' \; | sort > filelist.txt
find /home/user/OSN -type f -exec basename '{}' \; | sort | uniq -d > repeatlist.txt
else
ls -al /home/user/OSN  >2filelist.txt
fi

5 个答案:

答案 0 :(得分:5)

shell命令[也称为test,需要一个空格才能使shell正确解析。例如:

if [ "x$choice" == x"$same_name" ] ; then

相当于

if test "x$choice" == "x$same_name" ; then

在变量前加上“x”是一种习惯用法,可以防止test看到过少的参数。如果调用test 5 ==,测试会抱怨,如果$choice$same_name为空,则对expr的调用在语法上是正确的。

您还可以使用构造${choice:-default}${choice:=default}来防止未设置或null的shell变量。

答案 1 :(得分:3)

如果您收到了收到的错误消息,这将有所帮助。当我尝试这个时,我收到了错误:

./foo: line 9: [1: command not found

这使问题相当清楚。 [语句中的if运算符,在Unix中“从不使用复杂的东西,当一些简单的黑客将起作用”的风格时,只是另一个程序。 (请参阅ls /bin/[以获取证明!)因此,需要将其视为具有命令行选项的任何其他程序;你用空格将它与它的选项分开。否则,bash会认为“[$ choice”,连接,是要执行的程序的名称,并将尝试执行它。因此,该行必须是:

if [ $choice == "$same_name" ];then

在我改变之后,它起作用了。

另外,作为样式建议,我注意到当你有多个测试时,case构造是一种比使用if语句更容易编写代码的方法。并且,正如其他答案中所述,您应该在"周围放置$choice标记,以防止用户输入为空或包含空格的情况 - $choice,未加引号,将展开到由空格分隔的零个或多个标记的列表,而"$choice"总是扩展为单个标记。

答案 2 :(得分:1)

Bash的双方括号对引用以及null或unset变量更加宽容。

if [[ $choice == "$same_name" ]]; then

你应该看一下Bash的selectcase陈述:

choices="same_name filesize md5sum different_name exit"

PS3="Make a selection: "    # this is the prompt that the select statement will display
select choice in $choices
do
    case $choice in
        same_name)
            find ...
            ;;
        filesize)
            do_something
            ;;
        .
        .
        .
        exit)
             break
             ;;
    esac
done

答案 3 :(得分:1)

无法相信没有人收到此错误:如果您使用[(或test),字符串相等的运算符为=而非==

答案 4 :(得分:1)

你可以这样做。

while true
do
cat <<EOF
The list of choices are:
  1) same name
  2) filesize
  3) md5sum
  4) different name
  5) exit
EOF
read -r -p "Enter your choice: " choice
case "$choice" in
 1)
    find /home/user/OSN -type f -exec basename '{}' \; | sort > filelist.txt
    find /home/user/OSN -type f -exec basename '{}' \; | sort | uniq -d > repeatlist.txt
 5) exit;
 *) ls -al /home/user/OSN  >2filelist.txt
esac
done