简体   繁体   English

Bash:在case语句中的if / else语句中,Else不起作用

[英]Bash:Else not working in if/else statement in case statement

I am trying to check if a user types multiple arguments in a command line using case and if/else statements. 我正在尝试检查用户是否使用case和if / else语句在命令行中键入多个参数。 What's wrong is that I keep getting the default case instead of the same command, but with 2 more arguments. 出问题的是,我一直在使用默认大小写而不是相同的命令,但是还有两个参数。 For instance, one of my conditions is: 例如,我的条件之一是:

del)
    if [ -z "$2" ] || [ -z "$3" ]
    then
            echo "Usage: removes a file"
    else
    echo "using Bash command: rm $2 $3"
    rm $2 $3
    echo done
    fi

prints the first condition, but if I type, say, del aaa bbb, I get the default case, which is: 打印第一个条件,但是如果输入例如del aaa bbb,则会得到默认情况,即:

echo "ERROR: Unrecognized command"

I'm also using this to read a user's input, if that helps. 如果有帮助,我还将使用它来读取用户的输入。

read -p "wcl> " -r wcl $2 $3

I don't really know if there's a better way to solve this without scrapping all my code and starting from scratch. 我真的不知道是否有一种更好的方法可以解决此问题,而不必删除我的所有代码并从头开始。 This is the full code: 这是完整的代码:

#!/bin/bash
#use read command

echo Welcome to the Windows Command Line simulator!
echo Enter your commands below
while true
do
read -p "wcl> " -r wcl $2 $3
    case  $wcl  in
     dir)
    echo "using Bash command: ls  $2 $3"
    ls
    continue 
            ;;
    copy)
    FILE="$2"
    if [ "$#" -ne 3 ]
    then
         echo "Usage: copy sourcefile destinationfile"
    else
    echo "using Bash command: cp $2 $3"
    if [ -f "$FILE" ]
    then
    cp $2 $3
    else
    echo "cannot stat $FILE: No such file or directory">&2
    fi
    echo done
    fi
    continue
            ;;
    del)
    if [ -z "$2" ] || [ -z "$3" ]
    then
            echo "Usage: removes a file"
    else
    echo "using Bash command: rm $2 $3"
    rm $2 $3
    echo done
    fi
    continue
            ;;
    move)
    if [ -z "$2" ] || [ -z "$3" ]
    then
            echo "Usage: moves a file to another file name and location"
    else
    echo "using Bash command: mv $2 $3"
    mv $2 $3
    echo done
    fi
    continue
            ;;
    rename)
    if [ -z "$2" ] || [ -z "$3" ]
    then
            echo "Usage: renames a file"
    else
    echo "using Bash command: mv $2 $3"
    mv $2 $3
    echo done
    fi
    continue
            ;;
    ipconfig)
            ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1
    continue
            ;;
      exit)
            echo "Goodbye"
            exit 1
            ;;
    ^c)
            echo "Goodbye"
            exit 1
            ;;
*)
            echo "ERROR: Unrecognized command"
    continue
esac
done

You can't use read to set the positional parameters, although it isn't clear why you would need to here. 尽管尚不清楚为什么需要在此处设置,但您不能使用read来设置位置参数。 Just use regular parameters. 只需使用常规参数即可。

while true
do
    read -p "wcl> " -r wcl arg1 arg2
    case  $wcl  in
     dir)
    echo "using Bash command: ls  $arg1 $arg2"
    ls "$arg1" "$arg2"
    continue 
            ;;

    # ...
    esac
done

The way read -r wcl $2 $3 is executed is that $2 and $3 are first expanded to give names that read will use to set variables. 执行read -r wcl $2 $3方式是,首先扩展$2$3以提供read用来设置变量的名称。 If those aren't set, then the command reduces to read -r wcl , and so your entire command line is assigned to the variable wcl , not just the command. 如果未设置,则命令将减少为read -r wcl ,因此整个命令行都分配给变量wcl ,而不仅仅是命令。

However, read by itself is not going to do the same parsing that the shell already does, if you goal is to write your own shell. 但是,如果您的目标是编写自己的shell,那么read本身将不会执行与shell已经进行的相同的解析。

If you are really using bash, you can insert the words you read into positional parameters through an array. 如果您真的在使用bash,则可以通过数组将读取的单词插入位置参数中。 (You could also just leave them in the array, but the syntax for referring to positional parameters is simpler.) (您也可以将它们保留在数组中,但是引用位置参数的语法更简单。)

# -a: read the successive words into an array
read -r -p "wcl> " -a params
# set the positional parameters to the expansion of the array
set -- "${params[@]}" 
wcl=$1  # Or you could do the case on "$1"

This will also set $# to the number of words read, as a side-effect of setting the positional parameters. 这还会将$#设置$#读取的单词数,这是设置位置参数的副作用。

As @chepner points outs , the read is problematic: It simply splits the input into whitespace-separated words, without respecting quotes, backslashes, and whatever other shell metacharacters you might want to implement. 正如@chepner 指出的那样read是有问题的:它只是将输入拆分为用空格分隔的单词,而不考虑引号,反斜杠以及您可能要实现的任何其他shell元字符。 Doing a full bash-style parse of a command-line in bash itself would be quite a difficult exercise. 在bash本身中对命令行进行完整的bash样式解析将是非常困难的练习。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM