Bash编程(3) 命令行解析与扩展
$@表示脚本输入的全部参数,在bash脚本中,若$@增加引号("$@"),则包含空格的参数也会被保留,若不增加引号($@),则包含空格的参数会被拆分。
例:
# sa脚本内容如下:
pre=:
post=:
printf "$pre%s$post\n" "$@"
#printf "$pre%s$post\n" $@ # 注意$@增加引号和不加引号的区别
$ bash test.sh "a b"
:a b:
#:a:
#:b:
1. 引号
对于单引号、双引号、转义字符开头的空格,命令行解析时将不会被拆分。
$ sa \ this "is a" 'demonstration of' \ quotes\ and\ espaces ## quotes\ and\ espaces中会转义空格
: this:
:is a:
:demonstration of:
: :
:quotes and espaces: $ ./sa "a double-quoted single quote, '" "a double-quoted double quote, \"" # 单引号中的转义字符将失效,而双引号中的转义将有效
:a double-quoted single quote, ':
:a double-quoted double quote, ": $ ./sa 'a single-quoted double quotation mark, "'
:a single-quoted double quotation mark, ": $ ./sa "First argument "'still the first argument'
:First argument still the first argument: $ echo '\'line1\'\n\'line2\'' # 单引号中直接嵌套单引号,会有问题,即使增加转义符也无法正常执行 $ echo $'\'line1\'\n\'line2\'' # 增加$符号即可解决单引号中嵌套单引号的问题
2. 花括号
花括号作用于不带引号、以逗号分隔的列表或序列。当作为bash脚本的输入参数时,每个元素作为独立的参数。
$ ./sa {one,two,three}
:one:
:two:
:three:
$ ./sa {..} #bash3.0后增加
::
::
::
$ ./sa {a..c}
:a:
:b:
:c:
$ ./sa pre{d,}date # 花括号前后的字符串将包含在括号中的每个参数中
:preddate:
:pre1date:
$ ./sa {{..},{a..c}} # 花括号可以嵌套
::
::
::
:a:
:b:
:c:
$ ./sa {..}{a..c} # 连续多个的花括号将会逐个递归扩展
:1a:
:1b:
:1c:
:2a:
:2b:
:2c:
:3a:
:3b:
:3c:
$ ./sa {....} # .0版本的bash具有更高特性:数值序列前缀加0、可以指定序列中的步长
::
::
::
::
::
$ ./sa {a..h..} # 也可应用于字母
:a:
:d:
:g:
3. 波浪号
$ ./sa ~ # 不带引号的~表示当前用户的家目录
:/home/music: $ ./sa ~root # ~后带用户名,将表示该用户的家目录
:/root: $ ./sa "~" "~root" # 引号中的~将不会扩展
:~:
:~root:
$ dir=~root
$ dir2="~root"
$ ./sa "$dir" "$dir2"
:/root:
:~root: $ ./sa ~ws # ~后的用户名若不存在,则不扩展
:~ws:
4. 参数和变量扩展
$ var=whatever
$ ./sa "$var"
:whatever: $ var=qwerty
$ ./sa "${var}"
:qwerty: # 通常情况下,{}可选,当位置参数大于9或变量明后紧跟字符时,需要增加{}
$ first=Jane
$ last=Johnson
$ ./sa "$first_$last" #first_是有效变量名
:Johnson:
$ ./sa "${first}_$last"
:Jane_Johnson:
5. 算术扩展
$ ./sa "$(( 1 + 12 ))" "$(( 12 * 13 ))" "$(( 16 / 4 ))" "$(( 6 - 9 ))" "$(( 10 % 3 ))"
::
::
::
:-:
:: $ ./sa "$(( 3 + 4 * 5 ))" "$(( (3 + 4) * 5 ))"
::
:: # 将秒转为天、小时、分钟
secs_in_day=
secs_in_hour=
mins_in_hour=
secs_in_min= days=$(( $ / $secs_in_day ))
secs=$(( $ % $secs_in_day )) printf "%d:%02d:%02d:%02d\n" "$days" "$(( $secs / $secs_in_hour ))" \
"$(( ($secs / $mins_in_hour) % $mins_in_hour ))" "$(( $secs % $secs_in_min ))"
6. 命令替换
$ wc -l $( date +%Y-%m-%d ).log
--.log $ wc -l `date +%Y-%m-%d`.log # ``与$()作用相同
--.log
7. 分词
# 单词拆分基于内部字段分隔符(IFS)的值,默认IFS的为s' \t\n'
$ var="this is a multi-word value"
$ ./sa $var "$var"
:this:
:is:
:a:
:multi-word:
:value:
:this is a multi-word value: # 当IFS具有其默认值或未设置时,任何默认IFS字符序列都将作为单个分隔符读取
$ var=' spaced
> out '
$ ./sa $var
:spaced:
:out: # 当IFS包含另一个字符和空格时如" :",该" :"可以拆分字段,但每个分空白字符也可以拆分字段,即":"单独也会进行拆分
$ IFS=' :'
$ var="query : uiop : :: er"
$ ./sa $var
:query:
:uiop:
::
::
:er: # 当IFS仅包含非空字符时,则IFS中的每个字符拆分字段,且空格将保留
$ IFS=:
$ var="qwery : uiop : :: er"
$ ./sa $var
:qwery :
: uiop :
: :
::
: er:
8. 路径扩展
# 命令行中若包含*, ?, [,则将被当做文件匹配模式
$ ./sa h* # 匹配当前路径下以h开头的文件
:hw:
$ ./sa *e # 匹配当前路径下以k结尾的文件
:datafile:
:errorfile: $ ./sa ?a* # ?表示仅匹配一个字符
:datafile:
:sa: # [aceg]表示匹配a,c,e,g中的任意一个
# [h-o]表示匹配h到o中的任意字符
# [[:lower:]]表示匹配小写字母
9. 进程替换
进程替换将为命令创建一个临时文件。<(commond)使命令的输出像文件名一样可用;>(commond)表示可以写入的文件名。
# totalsize在循环外不可用
$ ls -l |
> while read perms links owner group size month day time file
> do
> printf "%10d %s\n" "$size" "$file"
> totalsize=$(( ${totalsize:=} + ${size:-} ))
> done
$ echo ${totalsize-unset} ## print "unset" if variable is not set # 命令替换可以使totalsize在循环外可用
$ while read perms links owner group size month day time file
> do
> printf "%10d %s\n" "$size" "$file"
> totalsize=$(( ${totalsize:=} + ${size:-} ))
> done < <(ls -l *)
$ echo ${totalsize-unset}
10. 解析选项
shell脚本中以-连接的选项,可以使用内置的getops解析。格式为:getopts OPTSTRING var
例:parseopts脚本
progname=${##*/} ## 获取脚本名称
# 默认值
verbose=
filename=
# 列出程序接收的选项列表,这些选项带参数,以:连接
optstring=f:v
# while循环调用getopts,直到命令无更多的选项
# 每个选项存储在$opt中,对应的选项参数存储在OPTARG
while getopts $optstring opt
do
case $opt in
f) filename=$OPTARG ;; # $OPTARG包含选项对应的参数
v) verbose=$(( $verbose + )) ;;
*) exit ;;
esac
done
# 命令行中移除选项
## $OPTIND指向下一个,且不解析参数
shift "$(( $OPTIND - 1 ))"
# 检查是否有文件传入
if [ -n "$filename" ]
then
if [ $verbose -gt ]
then
printf "Filename is %s\n" "$filename"
fi
else
if [ $verbose -gt ]
then
printf "No filename entered\n" >&
fi
exit
fi
# 检查文件是否存在
if [ -f "$filename" ]
then
if [ $verbose -gt ]
then
printf "Filename %s found\n" "$filename"
fi
else
if [ $verbose -gt ]
then
printf "File, %s, does not exist\n" "$filename" >&
fi
exit
fi
# 如果选择了verbose选项,打印保留在命令中的数值参数
if [ $verbose -gt ]
then
printf "Number of arguments is %d\n" "$#"
fi
执行命令结果如下:
$ ./parseopts
$ echo $? $ ./parseopts -v
No filename entered
$ echo $? $ ./parseopts -x
./parseopts: illegal option -- x
$ ./parseopts -vf qwerty
Filename is qwerty
File, qwerty, does not exist
$ ./parseopts -vf qwerty -- -x
Filename is qwerty
File, qwerty, does not exist
$ ./parseopts -vf ~/.bashrc
.bashrc .bashrc-anaconda3.bak
$ ./parseopts -vf ~/.bashrc -- -x
Filename is /home/music/.bashrc
Filename /home/music/.bashrc found
Number of arguments is
Bash编程(3) 命令行解析与扩展的更多相关文章
- python实现命令行解析的argparse的使用
参考https://docs.python.org/3.6/library/argparse.html argparse模块使编写用户友好的命令行界面变得很容易.程序定义了它需要什么参数,argpar ...
- Python 命令行解析工具 Argparse介绍
最近在研究pathon的命令行解析工具,argparse,它是Python标准库中推荐使用的编写命令行程序的工具. 以前老是做UI程序,今天试了下命令行程序,感觉相当好,不用再花大把时间去研究界面问题 ...
- Python命令行解析argparse常用语法使用简介
查看原文:http://www.sijitao.net/2000.html python中的命令行解析最简单最原始的方法是使用sys.argv来实现,更高级的可以使用argparse这个模块.argp ...
- Noah的学习笔记之Python篇:命令行解析
Noah的学习笔记之Python篇: 1.装饰器 2.函数“可变长参数” 3.命令行解析 注:本文全原创,作者:Noah Zhang (http://www.cnblogs.com/noahzn/) ...
- python命令行解析工具argparse模块【1】
argpaser是python中很好用的一个命令行解析模块,使用它我们可以很方便的创建用户友好型命令行程序.而且argparse会自动生成帮助信息和错误信息. 一.示例 例如下面的例子,从命令行中获取 ...
- 使用命令行解析php文件
使用命令行解析php文件,这样可以调用Log4PHP库中的一些demo,因为默认的输出使用命令行作为输出. 建一个bat文件: echo 以下是使用命令行解析php文件 C:\xampp\php\ph ...
- 『Argparse』命令行解析
一.基本用法 Python标准库推荐使用的命令行解析模块argparse 还有其他两个模块实现这一功能,getopt(等同于C语言中的getopt())和弃用的optparse.因为argparse是 ...
- python命令行解析模块--argparse
python命令行解析模块--argparse 目录 简介 详解ArgumentParser方法 详解add_argument方法 参考文档: https://www.jianshu.com/p/aa ...
- 【C++】cmdline——轻量级的C++命令行解析库
1.说明 cmdline是一个轻量级的c++命令行参数解析工具,全部源码只有一个cmdline.h头文件. 2.代码 20171210_命令行进行解析.cpp // 20171210_命令行进行解析. ...
随机推荐
- Android-Style样式
说到Style样式在,HTML+Javascript+CSS中,CSS就是样式,样式可以把很多通用到效果,统一为一个样式,达到通用的目的,也可以让代码更加简洁. 什么时候用Style样式 ? 例如:A ...
- [LeetCode 题解]:Intersection of Two Linked Lists
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Suppose an ...
- C语言程序设计
从 大一下 开始写博客,记录自己的学习. 而作为一个强迫症(比如我)是不允许做事缺头少尾的. 想了想还是得大一所学的C语言也搬上来,虽然结构老师经常嘲讽 (也不算嘲讽,算是絮叨吧)我的C语言,但是我还 ...
- [ZJOI2008] 树的统计Count
题目链接:戳我 树链剖分. 注意一点就是维护最大值的时候最好写成下面代码里那个样子,要不然会因为可能左右区间没有的问题有奇奇怪怪的锅. 代码如下: #include<iostream> # ...
- Collection 集合框架
1. Collection 集合框架:在实际开发中,传统的容器(数组)在进行增.删等操作算法和具体业务耦合在一起,会增加程序的开发难度:这时JDK提供了这样的容器---Collection 集合框架, ...
- Java反射机制与工厂模式
工厂模式属于创建型模式,它提供了一种创建对象的最佳方式. 它的特点是:客户端的程序类不直接牵扯到对象的实例化管理,只与接口发生关联,通过工厂类获取指定接口的实例化对象. 简单工厂模式如下: inter ...
- “全栈2019”Java第三十六章:类
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- centos6.3 配置 smb 服务
1.安装 samba 以及相关依赖包:yum install samba samba-client samba-swat 2.添加 smb 服务用户:smbpasswd -a user_name(之后 ...
- 浅析通过"监控"来辅助进行漏洞挖掘
这篇文章总结了一些笔者个人在漏洞挖掘这一块的"姿势",看了下好像也没相关类似TIPs或者文章出现,就写下此文. 本文作者:Auther : vulkey@MstLab(米斯特安全攻 ...
- Jupyter Notebook远程服务器配置[转]
首先要生成密码,打开python终端. In [1]: from IPython.lib import passwd In [2]: passwd() Enter password: Verify p ...