关于sed:bash,提示数字输入

bash, prompt for numerical input

D是我使用的一个内部服务器查找工具。

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

D$userinput(例如1234)

然后操作该查找的结果(下面将去掉除稍后要ping的IP地址之外的所有内容):

1
 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等。我只是不太熟悉如何正确格式化它,更重要的是:

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


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

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

1
2
3
4
5
6
7
8
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

regex [[ $number =~ ^[[:digit:]]+$ ]]确保用户只输入数字。

在这里,笨拙的(number=(10#$number))部分是这样的:如果用户输入一个以0开头的数字,bash会尝试用8基数来解释它,我们会得到错误的结果(例如,如果用户输入010),甚至在用户输入时出现错误,例如09(无此保护尝试)。

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

1
2
3
4
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函数:

1
2
3
4
5
6
7
8
9
10
11
die() {
    (($#)) && printf >&2 '%s
'
"$@"
    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

<编辑>

如果您只需要机械师提示,请尝试以下操作:

1
2
echo -n"Enter server number:"
read userinput

然后对输入运行验证检查,如下所示:

1
2
3
4
5
6
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

<结束编辑>

在第一次阅读时,我认为您的问题对于包装脚本来说是理想的,因此我建议您这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ 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"

然后这样调用脚本:

1
$ wrapper.sh 1243


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

1
2
3
4
5
6
 read x
 while [[ $x -lt 0 || $x -gt 9999 ]]; do
    echo"bad value for x"
    read x
 done
 echo"x=$x"

read命令本身不提示。在实际显示提示之前使用正常的echo。使用echo -n不添加新行。