linux shell编程-bash的奇技淫巧
本文主要讲bash脚本中容易出错和很少用但是用起来有意想不到效果的部分。
循环:
正常的for循环:
for i in a b c 1 2 3; do
echo "$i"
done
数字序列循环:
for i in `seq `; do
echo "$i"
done
其中的 `seq ` 也可以换成 {..}
{开始..结尾}的这种形式可以表示连续的数列,可以从小到大也可以从大到小,但是可惜不像python的range()那样可以指定间隔量
C语言风格的for循环:
for (( i=; i<; i++ )); do
echo "$i"
done
for循环迭代文本
for循环会使用空格、换行符、制表符分割文本,依次迭代,如:
a="ab cd
ef" for i in $a; do
echo "$i"
done
输出结果:
ab
cd
ef
shell分割文本其实是以一个全局变量$IFS为依据的,默认情况下IFS=$'\n\t '(即换行符、制表符、空格),可以通过修改IFS的值来改变迭代文本的分割方式。
请注意上面的$a如果加引号括起来的话,会把它当成一个整体,不会切割迭代。
数学计算
双括号“(())”还可以用于数学计算:
(( a=+ ))
echo $a
#
在双括号中,变量并不需要用$符号来引用,英文单词天然是变量。
变量:
间接引用:
a=b
b=
echo ${!a}
#
效果等同于 eval echo \$$a
特殊字符转义
包含特殊字符的字符串:
echo "ab\ncd"
上列命令会输出字符ab+换行+cd,但是实际上字符串"ab\ncd"中并不包含“换行”这个字符,输出的换行只是echo命令解析的结果。
# a="ab\ncd"
# echo "length of var a is ${#a}" length of var a is
通过${#var}的形式可以得到一个字符串的长度,上面示例可以看出来,字符串"ab\ncd"的长度是6而不是预期的5。
那么能否将不可打印的字符赋值给变量呢?答案是肯定的:
# a=$'\x61\n\x62'
# echo "$a"
a
b
请注意一定用的是单引号“'”,用双引号括起来是不起转义作用的。
字符串操作
变量值字符截取:
a="abcdefg"
echo ${a:}
# cdefg
echo ${a::}
# cde
变量值字符删除:(#为从头部开始匹配,%为从尾部匹配,支持通配符“?*”)
a="abdcdefgh"
echo ${a#*d} # 删除字符串头部匹配“*d”的部分,通配符*代表匹配任意多个字符,一个#号代表通配符“*”保守匹配
# cdefgh
echo ${a##*d} # 两个#号表示贪婪匹配
# efgh
echo ${a%d*} # 同上,两个%时代表贪婪匹配
# abdc
a=b
b="abcdefg"
echo "${!a#abc}"
# defg
可以同时支持间接引用和字符删除
变量赋值安全
用于赋值前检查是否已经定义或赋值。
unset a
unset b
b="" # a没有定义,b定义了但是空值
echo ${a-} # 如果没定义,则表达式采用默认值789
#
echo ${a:-} # 如果没定义或是空值,则表达式采用默认值789
#
echo ${b-} # 如果没定义,则表达式采用默认值789,b定义了
#
echo ${b:-} # 如果没定义或是空值,则表达式采用默认值789
#
echo $a # 原变量并没有被赋值
#
echo $b # 原变量并没有被赋值
#
b=
echo ${b-} # 如果变量已经被赋值,则不改变原有值
#
unset a
echo ${a=} # 如果a没定义,则表达式采用默认值,并给a赋值
#
echo $a
# # a已经被赋值了
a=""
echo ${a=}
#
echo ${a:=} # 加冒号:的作用和之前一样
#
echo $a
#
前面讲了用“-”和“=”的,还有一种用“+”的,用于当变量已经被赋值的情况下采用默认值,举一反三,不赘述了。
位置变量
$0是文件名,$#代表参数个数,$1,$2等等表示执行该脚本或函数后面跟的位置参数,$1代表第一个参数,依次类推,需要注意的是,第9个以后的参数应该这么表示:
${}
这表示第10个参数,必须用花括号括起来,否则就变成第1个变量后面加个字符“0”了。因为这个有的人以为第9个以后的位置变量就不可用了,是错的。
$@和$*都表示所有的变量,但是区别是前者将每个作为一个字符串,是多个字符串的结合,而后者将所有变量组合成一个字符串,用空格分隔。
这样不同会在for循环里面造成使用的区别,在for循环里面,如果加上引号 for i in "$@" 和 for i in "$*" 是不同的,前者还是会依次把参数代入循环,而后者会吧所有参数作为字符串一次性代入:
echo '
for i in "$@"; do
echo "$i"
done
for i in "$*"; do
echo "$i"
done
' > myscript.sh
chmod myscript.sh
./myscript.sh abc def
结果是:
abc def
abc def
那么$@加引号和不加引号有区别么?
大部分情况下结果看起来是一样的,但会在某些情况下造成麻烦,因为for循环会用换行符“\n”和空格来拆分变量,所以如果调用脚本所带的参数中带有空格或者换行符,不加引号的时候会把这个参数拆开了依次代入,而加了引号就可以避免这种情况。
echo '
for i in "$@"; do
echo "$i"
done
for i in $@ ; do
echo "$i"
done
' > myscript.sh
chmod myscript.sh
./myscript.sh abc "123 def"
结果是:
abc
def
abc def
for循环使用数组
将数组的值依次代入循环,可以用${arr[@}和${arr[*]}这两种方法,区别和加引号的区别同上面位置参数的使用相同。
字符串比较
shell的字符串匹配通常是这样的:
[ "abc" = "abc" ]
echo $?
#
$? 这个变量代表上条命令的返回码。若字符串相同则返回0,否则返回1。除了全匹配外,通过双方括号“[[]]”还可以用正则表达式匹配
[[ "abc234def" =~ ^abc[-]{}[a-z]+$ ]]
echo $?
#
注意这里正则表达式不能用引号括起来,而且只支持基本的正则,不支持如“\b \S”之类的扩展。
另单方括号‘[ ]’和双方括号‘[[ ]]’的区别,单括号等同于bash内置test命令,双方括号不是命令,是bash关键字。
原文地址:http://www.cnblogs.com/foxgab/p/6901782.html
如果觉得本文对您有帮助,请扫描后面的二维码给予捐赠,您的支持是作者继续写出更好文章的动力!
linux shell编程-bash的奇技淫巧的更多相关文章
- linux —— shell 编程(文本处理)
导读 本文为博文linux —— shell 编程(整体框架与基础笔记)的第4小点的拓展.(本文所有语句的测试均在 Ubuntu 16.04 LTS 上进行) 目录 基本文本处理 流编辑器sed aw ...
- linux —— shell 编程(编程语法)
导读 本文为博文linux —— shell 编程(整体框架与基础笔记)的第4小点的拓展.(本文所有语句的测试均在 Ubuntu 16.04 LTS 上进行) 目录 再识变量 函数 条件语句 循环语句 ...
- linux shell编程总结
linux shell编程总结 本周学习了unix/linux shell编程,参考的是<LINUX与UNIX Shell 编程指南>,David Tansley著:徐焱,张春萌等译,由机 ...
- Linux Shell编程参考大全
本文记录Linux Shell编程中常用基本知识,方便快速入门以及查询使用. 本文主要分为以下几个部分: 一.Shell中的变量 任何编程语言中,有关变量的定义,作用范围,赋值等都是最最基础的知识. ...
- linux shell 编程参考
#!/bin/bash my_fun() { echo "$#" } echo 'the number of parameter in "$@" is '$(m ...
- 一文学完Linux Shell编程,比书都好懂
一. Shell 编程 1. 简介 Shell 是一个用 C 语言编写的程序,通过 Shell 用户可以访问操作系统内核服务. Shell 既是一种命令语言,又是一种程序设计语言. Shell scr ...
- 前端学习 linux —— shell 编程
前端学习 linux - shell 编程 shell 原意是"外壳",与 kernel(内核)相对应,比喻内核外的一层,是用户和内核沟通的桥梁.shell 有很多种,国内通常使用 ...
- Linux Shell编程中的几个特殊符号命令 & 、&& 、 ||
https://blog.csdn.net/hack8/article/details/39672145 Linux Shell编程中的几个特殊符号命令 & .&& . || ...
- Linux Shell编程与编辑器使用详解
<Linux Shell编程与编辑器使用详解> 基本信息 作者: 刘丽霞 杨宇 出版社:电子工业出版社 ISBN:9787121207174 上架时间:2013-7-22 出版日期:201 ...
随机推荐
- hibernate 多对多关系总结
hibernate中,对对象关系的映射处理估计是最让人迷惑和头疼的,特别是cascade和inverse属性的使用,不知已经杀死了我多少个脑细胞了,好记性永远比不上烂笔头,为了能节省自己的脑细胞,降低 ...
- 线段树区间更新操作及Lazy思想(详解)
此题题意很好懂: 给你N个数,Q个操作,操作有两种,‘Q a b ’是询问a~b这段数的和,‘C a b c’是把a~b这段数都加上c. 需要用到线段树的,update:成段增减,query:区间求 ...
- 基于python的知乎开源爬虫 zhihu_oauth使用介绍
今天在无意之中发现了一个知乎的开源爬虫,是基于Python的,名字叫zhihu_oauth,看了一下在github上面star数还挺多的,貌似文档也挺详细的,于是就稍微研究了一下.发现果然很好用啊.就 ...
- 字符型SQL注入
字符型SQL注入 很早就基于DVWA实现了字符型的SQL注入,但是一直感觉自己没有理解的特别清楚,这次又看了一下网上的一些讲解,试着总结一下.以下是我的一写浅薄见解,请大家批判着看. 基本原理 看 ...
- hust1010 kmp
There is a string A. The length of A is less than 1,000,000. I rewrite it again and again. Then I go ...
- VMware安装CentOS 6.7系统
VMware安装CentOS 6.7系统 1. 安装前的准备 a) VMware虚拟机软件 b) CentOS 6.7镜像 c) Windows电脑一台 2. 开始安装 a) 打开VMware软件 b ...
- 用php(session)实现留言板功能----2017-05-09
要实现留言功能,发送者和接受者必不可少,其次就是留言时间留言内容. 要实现的功能: 1.登录者只能查看自己和所有人的信息,并能够给好友留言 2.留言板页面,好友采取下拉列表,当留言信息为空时,显示提示 ...
- 学习MVC之租房网站(七)-房源管理和配图上传
在上一篇<学习MVC之租房网站(六)-用户登录和权限控制>完成了后台用户登录和权限控制功能的开发,接下来要完成的是房源的管理,用户在后台新增.编辑房源信息,供前台用户操作. 一 房源管理 ...
- [笔记]cin、cout与scanf、printf的效率差异对比分析
之前上传UVa227 puzzle时,好不容易AC了,但发现自己用时50(ms),而在VJ上看到人家都是40ms.20ms,于是打开一个20ms的代码查看人家强在哪里.但结果研究了半天感觉差不多,于是 ...
- UML学习笔记之类之间的关系
1. 导航关系(Directed Association) A类有一个成员变量保存B的引用. 2.包含关系(Aggregation.Composition) (1)弱包含 含义:每个部门包含多个 ...