1

d 是我使用的内部服务器查找工具。

我希望允许用户输入 0(或 1)和 9999 之间的任何数字(我们称之为 userinput)并让它显示结果:

d $用户输入(例如 1234)

然后操纵该查找的结果(下面删除了除 IP 地址之外的所有内容以便稍后 ping):

 grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'`

我知道我需要使用 while true;请阅读 $blah 等。我只是不熟悉 read 足以正确格式化它,更重要的是:

让它提示输入 0-9999 之间的数字

4

4 回答 4

2

其他答案有很多缺陷,因为他们检查用户没有输入超出他们想要的范围的数字。但是如果用户输入的不是数字怎么办?他们的策略从一开始就被打破了。

相反,最好只有在我们确定用户输入的数字在所需范围内时才放手。

while :; do
    read -ep 'Enter server number: ' number
    [[ $number =~ ^[[:digit:]]+$ ]] || continue
    (( ( (number=(10#$number)) <= 9999 ) && number >= 0 )) || continue
    # Here I'm sure that number is a valid number in the range 0..9999
    # So let's break the infinite loop!
    break
done

正则表达式[[ $number =~ ^[[:digit:]]+$ ]]确保用户只输入数字。

笨拙的(number=(10#$number))部分在这里,如果用户输入一个以 a 开头的数字0,bash 会尝试以基数解释它,8我们会得到错误的结果(例如,如果用户输入010),甚至在以下情况下会出错用户输入,例如09(尝试不使用此防护)。


如果您只想在用户输入无效术语时提示一次并退出,您的逻辑是:

read -ep 'Enter server number: ' number
[[ $number =~ ^[[:digit:]]+$ ]] || exit 1
(( ( (number=(10#$number)) <= 9999 ) && number >= 0 )) || exit 1
# Here I'm sure that number is a valid number in the range 0..9999

如果您想向用户解释脚本退出的原因,您可以使用 die 函数:

die() {
    (($#)) && printf >&2 '%s\n' "$@"
    exit 1
}
read -ep 'Enter server number: ' number
[[ $number =~ ^[[:digit:]]+$ ]] ||
    die '*** Error: you should have entered a number'
(( ( (number=(10#$number)) <= 9999 ) && number >= 0 )) ||
    die '*** Error, number not in range 0..9999'
# Here I'm sure that number is a valid number in the range 0..9999
于 2014-04-22T17:49:44.497 回答
1

如果您只想要两个值之间的数字,则可以测试它们的值:

 read x
 while [[ $x -lt 0 || $x -gt 9999 ]]; do
    echo "bad value for x"
    read x
 done
 echo "x=$x"
于 2013-01-17T15:20:20.770 回答
1

<--编辑-->

如果你想要的只是提示机制,试试这个:

echo -n "Enter server number:"
read userinput

然后像这样对输入运行验证检查:

if [[ $userinput -lt 0 || $userinput -gt 9999 ]]   # checks that the input is within the desired range
 then
  echo "Input outside acceptable range."
else
  # insert your grep and ping stuff here
fi

<--结束编辑-->

在第一次阅读时,我认为您的问题对于包装脚本来说听起来很理想,所以我建议这样做:

$ cat wrapper.sh
#!/usr/bin/bash

userinput=$1

if [[ $# != 1 ]]   # checks that number of inputs is exactly one
 then
  echo "Too many inputs."
  exit 2
elif [[ $userinput -lt 0 || $userinput -gt 9999 ]]   # checks that the input is within the desired range
 then
  echo "Input outside acceptable range."
  exit 3
fi

output=`d "$userinput"`

ping_address=`grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' <("$output")`

ping "$ping_address"

然后像这样调用脚本:

$ wrapper.sh 1243
于 2013-01-17T15:31:28.287 回答
0

read命令不会提示自己。echo在实际显示提示之前使用法线。用于echo -n不添加换行符。

于 2013-01-17T15:18:34.387 回答