【shell】shell编程(五)-读取参数
  通过前⼏篇⽂章的学习,我们学会了shell的基本语法。在linux的实际操作中,我们经常看到命令会有很多参数,例如:ls -al 等等,那么这个参数是怎么处理的呢?接下来我们就来看看shell脚本对于⽤户输⼊参数的处理。
命令⾏参数处理
根据参数位置获取参数
  bash shell可根据参数位置获取参数。通过 $1 到 $9 获取第1到第9个的命令⾏参数。$0为shell名。如果参数超过9个,那么就只能通过${}来获取了,例如获取第10个参数,那么可以写为${10}。
⽰例⼀:
#!/bin/bash
#testinput.sh
echo "file name: $0"
echo "base file name: $(basename $0)"
echo "param1: $1"
echo "param2: ${2}"
运⾏上⾯的的shell
./testinput.sh 1234
最终得到的结果如下:
file name: ./testinput4.sh
base file name: testinput4.sh
param1: 12
param2: 34
成功的得到⽂件名和命令⾏输⼊的参数(命令⾏参数以空格分隔,如果参数包含了空格,那么久必须添
加引号了)$0默认会获取到当前shell⽂件的名称,但是,它也包含(./),如果你以完整路径运⾏,那么这还会包含⽬录名。因此,上⾯通过basename命令来获取单纯的⽂件名$(basename $0)。
试想⼀下,假如我们写的shell的这个参数很多,那如果像上⾯那样⼀个⼀个去获取参数,那岂不是要写疯!下⾯就来看看如何解决这种情况。
另外,还有⼏个特殊字符⽤来处理参数:
参数处理说明
$#传递到脚本的参数个数
$*以⼀个单字符串显⽰所有向脚本传递的参数。
如"$*"⽤「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$脚本运⾏的当前进程ID号
$!后台运⾏的最后⼀个进程的ID号
$@与$*相同,但是使⽤时加引号,并在引号中返回每个参数。
如"$@"⽤「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$-显⽰Shell使⽤的当前选项,与功能相同。
$?显⽰最后命令的退出状态。0表⽰没有错误,其他任何值表明有错误。
  上⾯重要的是$#和$?,$#可以获取参数的格式,$?可⽤于判断⼀个命令执⾏的状态。
例如下⾯⼀个批量删除⽤户的脚本就是根据$?获取上⼀个命令的执⾏状态码,然后判断是否正确执⾏命令:
#!/bin/bash
#delete user batch
echo "please input username word to delete"
read word
#get All users like word*
users=`/usr/bin/grep ${word} /etc/passwd | awk -F: -v word1=${word} 'index($1,wo
rd1)>0 {print $1}'`
if [ "${users}" = '' ]
then
echo "user is does not exist!"
exit 1
fi
for username in ${users}
do
/usr/sbin/userdel -rf ${username} > /dev/null2>/dev/null
done
if [ "0" = "$?" ]
then
echo "delete ok!"
else
echo "delete failed!"
fi
读取所有参数
⽅法⼀
既然bash shell通过位置可获取参数,那意味着如果我们知道参数的总个数就可以通过循环依次获取参数。那么如何获取参数总个数呢?
在bash shell中通过 $# 可获取参数总数。
⽰例:(循环获取参数)
#!/bin/bash
for (( index=0; index <= $#; index++ ))
do
echo ${!index}
done
  以上⽰例,我们通过 $# 获取总参数个数。然后通过循环获取每个位置的参数。注意:按照正常的理解,上⾯的 ${!index} 应该是 ${$index}才对,对吧?但是,由于${}内不能再写$符号,bash shell在这个地⽅是⽤了!符号,所以以上才写为了${!index}。
⽅法⼆
在bash shell中还可以通过 $* 和 $@ 来获取所有参数。但是这两者之间有着很⼤的区别:
$* 会将命令⾏上提供的所有参数当作⼀个单词保存, 我们得到的值也就相当于是个字符串整体。
$@ 会将命令⾏上提供的所有参数当作同⼀字符串中的多个独⽴的单词。
可能⽂字看起来描述的不太清楚,那么还是通过⽰例来看⼆者的区别吧:
#!/bin/bash
#testinput.sh
var1=$*
var2=$@
echo "var1: $var1"
echo "var2: $var2"
countvar1=1
countvar2=1
for param in"$*"
linuxshell脚本怎么运行do
echo "first loop param$countvar1: $param"
countvar1=$[ $countvar1 + 1 ]
done
echo "countvar1: $countvar1"
for param in"$@"
do
echo "second param$countvar2: $param"
countvar2=$[ $countvar2 + 1 ]
done
echo "countvar2: $countvar2"
执⾏上⾯的⽰例:
./testinput.sh 12 34 56 78
上⾯⽰例的输出结果为:
var1: 12 34 56 78
var2: 12 34 56 78
param1: 12 34 56 78
countvar1: 2
param1: 12
param2: 34
param3: 56
param4: 78
countvar2: 5
  通过上⾯的结果可见,直接输出看起来⼆者结果⼀样,但是通过for循环就可看出⼆者的区别了。上⼀
篇⽂章我们讲到for循环会通过IFS定义的值进⾏分割,因此默认情况下,如果我们上⾯在for循环处不加引号,那么根据IFS中所定义的空格分割,最终也会导致看不出⼆者区别。
获得⽤户输⼊
单个输⼊
有时候,我们在shell执⾏过程中获取⽤户的输⼊,以此与⽤户进⾏交互。这是通过read命令来实现的。下⾯就来看看其⽤法:
⽰例⼀:
#!/bin/bash
echo -n "yes or no(y/n)?"
read choice
echo "your choice: $choice"
  运⾏以上⽰例,⾸先会输出”yes or no(y/n)?“,然后会等待⽤户输⼊(-n参数表⽰不换⾏,因此会在本
⾏等待⽤户输⼊),当⽤户输⼊后,会把⽤户输⼊的值赋值给choice变量,然后最终输出 “your choice: (你输⼊的内容)”。
事实上,我们可以不指定read后⾯的变量名,如果我们不指定, read命令会将它收到的任何数据都放进特殊环境变量REPLY中。如下:
⽰例⼆:
#!/bin/bash
echo -n "yes or no(y/n)?"
read
echo "your choice: $REPLY"
以上⽰例与⽰例⼀是等价的。
有时候,我们需要⽤户输⼊多个参数,当然,shell是⽀持⼀次接受多个参数输⼊的。
多个输⼊
⽰例三:
#!/bin/bash
read -p "what's your name?" first last
echo first: $first
echo last: $last
  以上⽰例⾸先输出“what's your name?”,然后在本⾏等待⽤户输⼊(此处⽤read -p实现以上⽰例的echo -n + read命令的不换⾏效果),输⼊的参数以空格分隔,shell会把输⼊的值依次赋值给first和last两个变量。如果输⼊的值过多,假如我输⼊了3个值,那么shell会把剩下的值都赋值给最后⼀个变量(即第⼆三两个的值都会赋值给last变量)。
细想⼀下,有个问题,假如⽤户⼀直不输⼊,怎么办?⼀直等待?
超时设置
我们可以通过read -t 来指定超时时间(单位为秒),如果⽤户在指定时间内没输⼊,那么read命令就会返回⼀个⾮0的状态码。
⽰例四:
#/bin/bash
if read -t 5 -p "Please enter your name: " name
then
echo "Hello $name"
else
echo "Sorry, timeout! "
fi
  运⾏以上⽰例,如果超过5秒没输⼊,那么就会执⾏else⾥⾯的。
⼩结
  本篇简单的介绍了shell的输⼊参数以及接收⽤户输⼊。⼤家可以举⼀反三,结合之前所学的基础知识,可以写⼀些⼩的脚本应⽤了。
接下来可以学习shell编程六:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。