如果/ else有4个变量

时间:2014-05-05 23:21:23

标签: linux bash variables

确保用户准确输入信息的正确方法是什么,或者以正确的期望回复语句?我有一个bash脚本有4个变量,需要特定的输入形式,但我无法弄清楚如何检查他们的输入。

这些是我用来完成命令的变量:

read -p "Enter ID: " ID #SONGID can only be 10 digits long
read -p "Enter directory to search in e.g ab,cd,ef: " DIR #Directories are two letters and range from a-z
read -p "This abbreviation needs to match previous choice e.g ab, cd, ef: " FILE
read -p "Enter date of file e.g 20140503 or 201405*: " DATE

现在,无论如何,我的编写脚本的方式都会继续。

SONGID="10"
if [ $(echo "SONGID" | grep -E "[0-10") ] && 
    echo "Song ID good"
else
    echo "ID needs to be 10 digits"
    exit
fi

2 个答案:

答案 0 :(得分:1)

在进行检查之前尝试设置变量

INPUT_STATUS=good

然后执行检查,在发现错误时更改变量

case $SONGID in
  [[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]])
    # this matches when song IDs are 10 digits -- do nothing here
    ;;
  *)
    # this matches when song IDs are not 10 digits -- we're bad now
    INPUT_STATUS=bad
    ;;
esac

if [ $INPUT_STATUS = 'good' ]; then
  echo "Song ID is good."
else
  echo "Song IDs need to be exactly 10 digits."
fi

每次检查成功时,不要试图设置INPUT_STATUS=good

使用case语句可以指定与SONGID grep匹配的模式。或者,现代shell可能允许我们使用conforms to POSIX。使用shell可以使用的模式给我们带来的额外好处是比调用像{{1}}之类的外部程序来进行匹配要快得多。

答案 1 :(得分:1)

您可以使用类似于以下的模式。纯粹的狂欢。您确定当您离开while循环时数据已经过相应的功能验证 - 所以如果出现问题,您将不得不责怪该功能,而不是程序的结构 1

#!/bin/bash

validate_ID() {
    # Success if and only if $1 is a string of 10 digits
    [[ $1 =~ ^[[:digit:]]{10}$ ]]
}

validate_dir() {
    # Success if and only if $1 is a string of 2 letters in the range [a-z]
    [[ $1 =~ ^[abcdefghijklmnopqrstuvwxyz]{2}$ ]]
    # Hard-coded here for security, since depending on locales, other characters
    # would pass, e.g., é. Try it: [[ é =~ [a-z] ]]; echo $?
}

validate_file() {
    # I didn't understand the requirements... this always succeeds for now
    return 0
}

validate_date() {
    # Don't know how you want to validate this... this always succeeds for now
    return 0
}

while :; do
    IFS= read -rep "Enter ID: " songID
    history -s -- "$songID"
    validate_ID "$songID" && break
    echo "Bad ID"
done

while :; do
    IFS= read -rep "Enter directory to search in e.g ab,cd,ef: " dir #Directories are two letters and range from a-z
    history -s -- "$dir"
    validate_dir "$dir" && break
    echo "Bad dir"
done

while :; do
    IFS= read -rep "This abbreviation needs to match previous choice e.g ab, cd, ef: " file
    history -s -- "$file"
    validate_file "$file" && break
    echo "Bad file"
done

while :; do
    IFS= read -rep "Enter date of file e.g 20140503 or 201405*: " date
    history -s -- "$date"
    validate_date "$date" && break
    echo "Bad date"
done

history命令:每个命令都将读入的值插入历史记录中,以便用户可以使用向上箭头(尝试使用和不使用)检索以前的值 - 注意-e标志到read命令使用readline。 TAB完成适用于文件名。

注意。目前有两种验证功能无法完成工作。我并不完全了解您希望如何验证数据。


1 其他一些REPL设计可能会失败,例如,

while read a; do
    validate "$a" && break
    echo "$a is invalid"
done

似乎很好,但如果读取中出现错误,则会失败,例如,用户可以输入任意数据,按Ctrl-D几次,您将拥有该任意数据变量a