shell 脚本中关于用户输入参数的处理
bash shell 脚本提供了3种从 用户处 获取数据的方法:
命令行参数(添加在命令后的数据)
命令行选项
直接从键盘读取输入
像 shell 脚本传递数据的最基本方法是使用 命令行参数.
示例:
./add.sh 10 20
本例向脚本 add.sh 传递了两个 命令行参数(10 和 20).
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 numbe
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
如果把 "$*" 上的双引号 "" 去掉, $* 会输出和 "$@" 一样的结果.
这里介绍两个常用的 参数扩展 :
${variable_name:-value}: 如果 variable_name 的值为空, 返回 value.
${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
选项(option) 是跟在 破折号(dash -) 后面的单个字母, 它能改变命令的行为.
处理 选项 涉及到 getopt 和 getopts 命令.
这里从略, 等有需要用到再回来补上.
尽管 命令行选项 和 参数 是从 用户处 获取输入的一种重要方式, 但有时脚本的交互性还需更强一些.
比如在脚本运行时问一个问题, 等待运行脚本的人来回答, bash shell 为此提供了 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:
read -p “prompt text” variable_name: -p here stands for the prompt. Here we read the data along with some hint text .
read -s variable_name: This option -s means secret or secure whatever is used to read the sensitive data.
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 !!!
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
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。