脚本Unix(不等于字符串)

时间:2017-11-21 12:41:32

标签: unix

我写了以下代码:

echo "Choose between the following options:"
echo "1 - Create a new file"
echo "2 - Write in an existing file"
echo "3 - Change the path of a file"
echo "4 - Display a file"
echo "5 - Exit"

read number

while [ $number -ne 1 -o $number -ne 2 -o $number -ne 3 -o $number -ne 4 -o $number -ne 5 ]
do
    echo "Enter a number between 1 and 5"
    read number
done

if [ $number -eq 1 ]; then
    echo "Enter a folder name"
    read name
    while [ -e $name ]
    do
        echo "The file name already exists enter a new name:"
        read name
    done
    touch $name
fi

if [ $number -eq 2 ]; then
    echo "Enter the folder name you want to edit :"
    read name
    while [ ! -f $name ]
    do
        echo "The file you are looking does not exist. Enter another file name :"
        read name
    done
    echo "Enter what you want to put in the file :"
    read input
    echo $input >> $name
fi

if [ $number -eq 3 ]; then
    echo "Enter the folder name :"
    read name
    while [ ! -f $name ]
    do
        echo "The file you are looking does not exist. Enter another file name :"
        read name
    done

if [ $number -eq 4 ]; then
    echo "Enter the folder name you want to see :"
    read name
    while [ ! -f $name ]
    do
        echo "The file you are looking does not exist. Enter another file name :"
        read name
    done
    cat $name
fi

if [ $number -eq 5 ]; then
    exit 0
fi

代码工作正常,但在第一个条件下:

while [ $number -ne 1 -o $number -ne 2 -o $number -ne 3 -o $number -ne 4 -o $number -ne 5 ]

我希望它适用于我放的任何数字或字符串。 例如,如果我放hello程序将崩溃。 有人能告诉我我的第一个条件应该是什么?

感谢您的帮助。如果我的问题不在论坛的规则中(我刚刚订阅),请原谅我。

2 个答案:

答案 0 :(得分:1)

我强烈建议使用case语句构建代码:

case $number in
1) code_for_1;;
2) code_for_2;;
...
*) echo "Invalid number" >&2;;
esac

如果您希望重复(我实际上建议将该数字作为命令行参数而不是从stdin读取并中止错误),您可以这样做:

while read number; do
    case $number in
    ...
    *) echo 'Invalid number' >&2; continue;;
    esac
    break
done

并将code_for_ {1,2,3,4,5}写为分解逻辑的函数。例如:

create_file() { 
    echo "Enter a file name"
    while read name; do
        if test -e "$name"; then
            echo "The file $name already exists enter a new name" >&2
            continue
        fi
        touch "$name"
        break
    done
} 

while read number; do  
    case $number in
    1) create_file;;
    ...
    *) echo 'Invalid number' >&2; continue;;
    esac
    break
done

答案 1 :(得分:1)

你的剧本说:

while [ $number -ne 1 -o $number -ne 2 -o $number -ne 3 -o $number -ne 4 -o $number -ne 5 ]

因此,如果$number为1,则它不等于2.如果它是2,则它不等于1.这将始终评估为 true ,所以你永远不会退出循环。

存在多种与数字值兼容且仍可正常处理非数字输入的选项。以下使用基本正则表达式来确定输入是否为1到5之间的数字:

while read number && ! expr "$number" : '[1-5]$' >/dev/null; do
  echo "Try again" >&2
done

但是,使用案例陈述可能会更好:

while read number; do
  case "$number" in
    1) function_1 ;;
    2) function_2 ;;
    ... etc
    *) echo "Invalid input, please try again." >&2; continue ;;
  esac
  break
done

case语句是一种更优雅的方式来表达使用if..elif..elif..fi可能实现的目标:

while read number && ! expr "$number" : '[1-5]$' >/dev/null; do
  echo "Try again" >&2
done

if [ "$number" = 1 ]; then
  : do_something
elif [ "$number" = 2 ]; then
  : do_something
elif [ "$number" = 3 ]; then
  : do_something
elif [ "$number" = 4 ]; then
  : do_something
elif [ "$number" = 5 ]; then
  : do_something
else
  echo "What am I doing?" >&2
fi

虽然这个结构在技术上有效,但它不够优雅且难以阅读。将您的功能放入从案例陈述调用的函数中会更好。

请注意,在这样的脚本中引用变量总是一个好主意。你知道不带引号的变量会发生什么吗?如果没有,则引用您的变量。 :)