【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
最终得到的结果如下:
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使用的当前选项,与set命令功能相同。 |
| $? | 显示最后命令的退出状态。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)> {print $}'`
if [ "${users}" = '' ]
then
echo "user is does not exist!"
exit
fi
for username in ${users}
do
/usr/sbin/userdel -rf ${username} > /dev/null >/dev/null
done
if [ "" = "$?" ]
then
echo "delete ok!"
else
echo "delete failed!"
fi
读取所有参数
方法一
既然bash shell通过位置可获取参数,那意味着如果我们知道参数的总个数就可以通过循环依次获取参数。那么如何获取参数总个数呢?
在bash shell中通过 $# 可获取参数总数。
示例:(循环获取参数)
#!/bin/bash
for (( index=; 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=
countvar2=
for param in "$*"
do
echo "first loop param$countvar1: $param"
countvar1=$[ $countvar1 + ]
done
echo "countvar1: $countvar1" for param in "$@"
do
echo "second param$countvar2: $param"
countvar2=$[ $countvar2 + ]
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 -p "Please enter your name: " name
then
echo "Hello $name"
else
echo "Sorry, timeout! "
fi
运行以上示例,如果超过5秒没输入,那么就会执行else里面的。
小结
本篇简单的介绍了shell的输入参数以及接收用户输入。大家可以举一反三,结合之前所学的基础知识,可以写一些小的脚本应用了。
接下来可以学习shell编程六:http://www.cnblogs.com/qlqwjy/p/8683972.html
【shell】shell编程(五)-读取参数的更多相关文章
- centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件、目录属性 shell数组简单用法 $( ) 和${ } 和$(( )) 与 sh -n sh -x sh -v 第三十五节课
centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件.目录属性 shell数组简单用法 $( ) 和$ ...
- 实验五:shell脚本编程
项目 内容 这个作业属于哪个课程 班级课程的主页链接 这个作业的要求在哪里 作业要求链接地址 学号-姓名 17043133-木腾飞 作业学习目标 1.了解shell 脚本的概念及应用2.掌握shell ...
- 实验五 shell脚本编程
项目 内容 这个作业属于哪个课程 课程链接 这个作业的要求在哪里 作业要求 学号-姓名 17041428-朱槐健 作业学习目标 1. 了解shell脚本的概念及使用 2.掌握shell脚本语言的基本语 ...
- 实验五shell脚本编程
项目 内容 这个作业属于哪个课程 <班级课程的主页链接> 这个作业的要求在哪里 作业要求链接地址 学号-姓名 17043220-万文文 作业学习目标 1)了解shell脚本的概念及使用.2 ...
- SHELL脚本编程的常识和VI常用技巧
来源:http://mprc.pku.edu.cn/mentors/training/TrainingCourses/material/ShellProgramming.HTM#_Toc3751808 ...
- SHELL脚本编程基础知识
SHELL脚本编程基础知识 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Linux之父Linus有一句话很经典:"Talk is cheap, show me the ...
- SHELL脚本编程的条件测试
SHELL脚本编程的条件测试 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.条件测试概述 判断某需求是否满足,需要由测试机制来实现 专用的测试表达式需要由测试命令辅助完成测试过 ...
- Linux零基础之shell基础编程入门
从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁.用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操 ...
- Linux shell脚本编程(一)
Linux shell脚本编程: 守护进程,服务进程:启动?开机时自动启动: 交互式进程:shell应用程序 广义:GUI,CLI GUI: CLI: 词法分析:命令,选项,参数 内建命令: 外部命令 ...
随机推荐
- Java容器深入浅出之List、ListIterator和ArrayList
List是Collection接口的子接口,表示的是一种有序的.可重复元素的集合. List接口的主要实现类ArrayList和Vector,底层都是维护了一套动态的,可扩展长度的Object[]数组 ...
- [BinaryTree] 二叉树常考知识点
1.二叉树第i层至多有2^(i-1)个结点(i>=1). 2.深度为k的二叉树上,至多含2^k-1个结点(k>=1) 3.n0 = n2 + 1(度) 4.满二叉树:深度为k且含有2^k- ...
- Distributed transactions in Spring, with and without XA
While it's common to use the Java Transaction API and the XA protocol for distributed transactions i ...
- adb命令模拟按键事件KeyCode
例子: //这条命令相当于按了设备的Backkey键 adb shell input keyevent 4 //可以解锁屏幕 adb shell input keyevent 82 //在屏幕上做划 ...
- python判断字符串是否包含子字符串
python的string对象没有contains方法,不可以使用string.contains的方法判断是否包含子字符串,但是python有更简单的方法来替换contains函数 python的st ...
- 实现对一个8bit数据的指定位的置0或者置1操作,并保持其他位不变。
给定函数原型:void bit_set(unsigned char *p_data,unsigned char positin,int flag) 参数说明:p_data是指定的源数据:positio ...
- 黑客帝国雨效果JS
黑客帝国雨效果JS. <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- 洛谷P3938 斐波那契
题目戳 题目描述 小 C 养了一些很可爱的兔子. 有一天,小 C 突然发现兔子们都是严格按照伟大的数学家斐波那契提出的模型来进行 繁衍:一对兔子从出生后第二个月起,每个月刚开始的时候都会产下一对小兔子 ...
- 洛谷P1273 有线电视网 【树上分组背包】
题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从 ...
- iframe在ios上不能滚动问题解决
同这篇文章一样,用到了-webkit-overflow-scrolling: touch;属性.主要解决方案是在iframe外层添加一个div,然后设置-webkit-overflow-scrolli ...