shell 脚本处理用户输入

bash shell 脚本提供了3种从 用户处 获取数据的方法:

  1. 命令行参数(添加在命令后的数据)
  2. 命令行选项
  3. 直接从键盘读取输入

1 命令行参数

像 shell 脚本传递数据的最基本方法是使用 命令行参数.

示例:

./add.sh 10 20

本例向脚本 add.sh 传递了两个 命令行参数(10 和 20).

1.1 读取命令行参数

bash shell 中有一些特殊变量, 被称为 位置参数(positional parameter).

位置参数的标准数字是:
$0 是程序名;
$1 是第一个参数;
$2 是第二个参数;
依次类推, $9 是第九个参数.
${10} 是第十个参数…

看一个求 阶乘(factorial) 的例子:

$ cat temp.sh
#!/bin/bash
factorial=1
for (( i=1; i<=$1; i++)); do
    factorial=$[$factorial * $i]
done
echo "the factorial of $1 is $factorial"

$ ./temp.sh 4
the factorial of 4 is 24

如果 shell 脚本需要用到 命令行参数, 但是脚本运行时却没有加 命令行参数, 可能会出问题, 比如上面的例子中, 如不加参数运行会报错:

$ ./temp.sh
./temp.sh: line 3: ((: i<=: syntax error: operand expected (error token is "<=")
the factorial of  is 1

一般我们需要检查 命令行参数 , 改造一下上面的例子:

$ cat temp.sh
#!/bin/bash
# 命令行参数1 字符串长度是否是 zero
if [ -z "$1" ]; then
    echo "usage: $0 number"
    exit 0
fi
factorial=1
for (( i=1; i<=$1; i++)); do
    factorial=$[$factorial * $i]
done
echo "the factorial of $1 is $factorial"

$ ./temp.sh
usage: ./temp.sh number

bash shell 还提供了几个特殊的变量:
$# 脚本运行时携带的 命令行参数的个数;
$* 将命令行上提供的 所有参数 当做 一个单词 保存;
$@ 将命令行上提供的 所有参数 当做 多个独立的单词 保存.

示例:

$ cat temp.sh
#!/bin/bash
echo "There wre $# parameters supplied."
count=1
for param in "$*"; do
    echo "\$*, 参数$count = $param"
    count=$[ $count + 1 ]
done
count=1
for param in "$@"; do
    echo "\$@, 参数$count = $param"
    count=$[ $count +1 ]
done

$ ./temp.sh miyan rosie abby
There wre 3 parameters supplied.
$*, 参数1 = miyan rosie abby
$@, 参数1 = miyan
$@, 参数2 = rosie
$@, 参数3 = abby

如果把 "$*" 上的双引号 "" 去掉, $* 会输出和 "$@" 一样的结果.

1.2 shell parameter expansion

这里介绍两个常用的 参数扩展 :

  1. ${variable_name:-value}: 如果 variable_name 的值为空, 返回 value.
  2. ${variable_name:?msg}: 如果 variable_name 的值为空, 返回message错误并退出.

示例:

$ cat temp.sh
#!/bin/bash
name=${1:? user name cannot be empty}
password=${2:-$(uuidgen | tr '[:upper:]' '[:lower:]')}
echo "username: $name, passowrd: $password"

$ ./temp.sh
./temp.sh: line 2: 1:  user name cannot be empty

$ ./temp.sh miyan
username: miyan, passowrd: e2c7956c-cd6c-4761-a323-a6785587b8f9

2 命令选项

选项(option) 是跟在 破折号(dash -) 后面的单个字母, 它能改变命令的行为.
处理 选项 涉及到 getoptgetopts 命令.
这里从略, 等有需要用到再回来补上.

3 获取用户输入

尽管 命令行选项参数 是从 用户处 获取输入的一种重要方式, 但有时脚本的交互性还需更强一些.
比如在脚本运行时问一个问题, 等待运行脚本的人来回答, bash shell 为此提供了 read 命令.

3.1 read 命令

read variable_name 从标准输入(键盘) 或 另一个文件描述符中 接受输入, 在收到输入后, read 会将数据存入变量中.

read 命令示例:

$ cat temp.sh                                                                                                                                                    
#!/bin/bash
# -n, don't output the trailing newline.
echo -n "Enter you name: "
read name
echo "Hello $name"

$ ./temp.sh
Enter you name: miyan
Hello miyan

read 有3个常用 选项 -p, -s-t:

  1. read -p “prompt text” variable_name: -p here stands for the prompt. Here we read the data along with some hint text .
  2. read -s variable_name: This option -s means secret or secure whatever is used to read the sensitive data.
  3. read -t seconds variable_name: 设置 timeout 时间, 单位秒, 超时返回非 0 退出状态码.

read 读取多个变量时, 多个变量用空格分隔:

$ cat temp.sh
#!/bin/bash
read -p "three names: " u1 u2 u3
echo "Hello $u1, $u2, $u3 !!!"

$ ./temp.sh
three names: miyan rosie abby
Hello miyan, rosie, abby !!!

3.2 从文件中读取

read 命令可以读取文件中保存的数据. 每次调用 read 命令, 它都会读取一行文本. 当文件中没有内容时, read 会退出并返回非 0退出状态码.

问题是怎么将文件的数据传给 read ?
最常见的方法是 对文件使用 cat 命令, 将结果通过 管道 直接传给 含有 read 命令的 while 命令.

看个例子:

$ cat test.txt
狂浪生
hotel california
nothing's gonna change my love for you

$ cat temp.sh
#!/bin/bash
count=1
cat test.txt | while read line; do
    echo "line $count: $line"
    count=$[ $count + 1 ]
done

$ ./temp.sh
line 1: 狂浪生
line 2: hotel california
line 3: nothing's gonna change my love for you

还有一种高级的写法, 用 输入重定向 :

$ cat temp.sh
#!/bin/bash
count=1
while read line; do
    echo "line $count: $line"
    count=$[ $count + 1 ]
done < test.txt

$ ./temp.sh
line 1: 狂浪生
line 2: hotel california
line 3: nothing's gonna change my love for you
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值