shell 处理用户的输入

shell 处理用户的输入
1、命令行参数
$ ./dome.sh  10  30 
传递参数10和30


读取参数
shell会将一些称为位置参数的特殊变量分配给命令行输入的所有
参数。位置参数变量是标准的数字:$0是程序名,$1是第一个
参数,$2是第二个参数,以此类推,直到第9个参数$9。
#!/bin/bash
factorial=1
for (( number=1; number <= $1; number++ ))
do
factorial=$[ $factorial * $number ]
done
echo the factorial of $1 is $factorial
命令行参数输入多个时,要使用空格分开。如果字符串需要
空格分割时,需要使用引号括起来。
如果脚本的变量多于9个命令行参数,修改一下变量名,仍然
可以使用,你必须在变量数字周围加花括号,比如${10}。




读取程序名
#!/bin/bash
# use basename with the $0 parameter


name=`basename $0`
echo the command entered is:$name
因为$0读取的程序名,会包含程序的路径,可以使用
basename命令让只返回程序名,而不要路径。


特殊变量 
$#特殊变量含有脚本运行时就有的命令行参数,你可以在脚本
的任何地方使用这个特殊变量。
$#这个特殊变量可以判断输入多少个变量,从而避免我们对
每个变量都要判断是否存在。
$#变量含有参数的总数值,那么变量$($#)就代表了最后一个
命令行参数变量,但是会出现错误,因为不能在花括号内使用
美元符,你必须把美元符换成感叹号,$(!#)这样的格式才能
正常显示。
而且,在没有参数 的情况下$(!#)可以返回程序名。


抓取所有的数据
$*和$@变量会将命令行上提供的所有参数当作单个单词保存,
$*变量会将这些都当做一个参数,而不是多个对象。
$@变量会将命令行上提供的所有参数当做同一字符串中的
多个独立的单词,它允许你遍历所有的值,将提供的每个参数 
分割开来,而不是多个对象。
例子:
#!/bin/bash
# testing $* and $@
count=1
for param in "$*"
do
echo "\$* paramter #$count-$param"
count=$[ $count + 1 ]
done


count=1
for param in "$@"
do
echo "\$@ paramter #$count-$param"
echo=$[ $count + 1 ]
done
结果:
[root@localhost sh]# ./14.sh 222 333 222  444
$* paramter #1-222 333 222 444
$@ paramter #1-222
$@ paramter #1-333
$@ paramter #1-222
$@ paramter #1-444




移动变量
bash shell中的工具shift命令,可以操作命令行参数。shift
命令会根据它们的相对位置来移动命令行参数。
在使用shift命令时,默认情况下它会将每个参数变量减一
注意变量$0的值,也就是程序名是不会改变的。
注意:使用 shift命令时要小心,当一个参数被移除后,它的
值会被丢掉并且无法恢复。


处理带值的选项例子:
#!/bin/bash
# extracting command line iption and values
while [ -n "$1" ]
do
case "$1" in
-a)echo "Found the -a option";;
-b)param="$2"
   echo "Found the -b option,with paramter value $param"
   shift 2;;
-c)echo "Found the -c option";;
--)shift
   break;;
*)echo "$1" is  not an option;;
esac
shift
done


count=1
for param in "$@"
do
echo "paramter #count:$param"
count=$[ $count + 1 ]
done


使用getopt命令
getopt命令是一个在处理命令行选项和参数时非常方便的工具
,它能够识别命令行参数,从而在脚本中解析它们时更方便。
1、命令格式 
getopt   options  optstring parameters
optstring定义了命令行有效的选项字母,还定义了哪些选项
字母需要参数值。
首先在optstring中列出你要在脚本中用到的每个命令行选项
字母,然后在每个需要参数值的选项字母后加一个冒号。
#!/bin/bash
# extracting command line options and values with getopt


set -- `getopt -q ab:c "$@"`
while [ -n "$1" ]
do
case "$1" in
-a)echo "FOund the -a option";;
-b)param="$2"
   echo "Found the -b option.with parameter value $param";;
-c)echo "Found the -c option";;
--)shift
   break;;
*)echo "$1 is not an option";;
esac
shift
done


count=1
for param in "$@"
do 
echo "parameter #$count:$param"
count=$[ $count + 1 ]
done


使用getopt不能区分两个参数写在一块的情况,比如-ac
因此shell升级了一个命令,使用getopts来处理
#!/bin/bash
# processing options and parameters with getopts
while getopts :ab:cd opt
do
case "$opt" in
a)echo "Found the -a option";;
b)echo "Found the -b option with value $OPTARG";;
c)echo "Found the -c option";;
d)echo "Found the -d option";;
*)echo "Unknown option $opt";;
esac
done
shift $[ $OPTIND - 1 ]


cound=1
for  param in "$@"
do
echo "parameter $count: $param"
count=$[ $count + 1 ]
done


getopts命令格式:
getopts optstring  variable
optstring值类似于getopt命令中的那个,有效的选项字母都
会列早optstring中,如果选项字母要求有个参数值,就加
一个冒号。要去掉错误消息的话,可以在optstring之前加
一个冒号。getopts命令将当前参数保存在命令行中定义的
variable中。
getopts命令会用到两个环境变量,如果选项需要跟一个参数
值,OPTARG环境变量就会保存这个值。OPTIND环境变量
保存了参数列表中getopts正在处理的参数位置,这样你就
能在处理完选项之后继续处理其他命令行参数了。
getopts命令解析行选项时,它会移除开头的单破折线,所以
case定义中不用单破折线。
getopts的几个好处
1、参数值中可以包含空格 
2、将选项字母和参数值放在一起使用,而不用加空格
3、把能够将命令行上找到的所有未定义的选项统一输出
成问号。
在getopts处理每个选项时,它会将OPTIND环境变量值增一,
在getopts完成处理时,你可以将OPTIND值和shift命令一起
使用来移动参数。


通用的Linux命令选项
选项         描述
-a     显示所有对象
-c 生成一个计数
-d 指定一个目录
-e 扩展一个对象
-f  指定读入数据的文件
-h 显示命令的帮助信息
-i 忽略文本大小写
-l    产生输出的长格式版本
-n 使用非交互模式(批量)
-o 指定将所有输出重定向到的输出文件
-q 以安静模式运行
-r 递归地处理目录和文件
-s 以安静模式运行
-v 生成详细输出
-x 排除某个对象
-y 对所有问题问答yes


获得用户的输入
read命令接受从标准输入(键盘)或另一个文件描述符的输入
在收到输入后,read命令会将数据放进一个标准变量。
read -p  “please  enter your name:”  age
read命令会为提示符输入的所有数据分配一个变量,或者你
也可以指定多个变量。输入的每个数据值都会分配给表中的
下一个变量,如果变量表在数据之前用完了,剩下的数据就
都会分配给最后一个变量。
你可以在read命令行中不指定变量,如果那么做了,read命令
会将它收到的任何数据都放进特殊环境变量REPLY中:
REPLY环境变量会保存输入的所有数据,它可以在shell脚本
中像其他变量一样使用。


read命令在用户不输入的情况下会一直等下去,因此我们可以
使用计时器,-t选项指定了read命令等待输入的秒数。当计时器
过期后,read命令会返回一个非零退出状态码。
#!/bin/bash
# testing the read entry
if read -t 5 -p "Please enter your name:" name
then
echo "Hello $name,Welcome to my script!"
else
echo 
echo "sorry,too slow!"
fi
可以使用read命令来对输入的字符计数。当输入的字符达到
预设的字符数时,它会自动退出,将输入的数据赋给变量。
#!/bin/bash
# getting just one character of input


read -n1 -p "Do you want to continue[Y/N]?" answer
case $answer in
Y|y)echo
    echo "first, continue on ...";;
N|n)echo
    echo "OK,goodbye!"
    exit;;
esac
echo "This is the end of the script"
其中-n选项和值1一起使用,告诉read命令在接受单个字符
后退出,只要你按下单个字符回答后,read命令就会接受
输入并将它传给变量,而不必按回车键。


隐藏方式读取
-s选项会阻止将传给read命令的数据显示在显示器上(实际上
,数据会被显示,只是read命令会将文本 颜色设成跟背景色
一样)。但是输入的数值会赋给变量,以便脚本在脚本中使用。


从文件中读取
每次调用read命令会从文件中读取一行文本,当文本中再没有
内容时,read命令会退出并返回非零退出状态码。
#!/bin/bash
# reading data from a file
count=1
cat test | while read line
do
echo "Line $count: $line"
count=$[ $count + 1 ]
done
echo "Finished processing the file"

你可能感兴趣的:(linux,shell,运维)