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 ...
随机推荐
- Let's Encrypt: 为CentOS/RHEL 7下的nginx安装https支持-具体案例
环境说明: centos 7 nginx 1.10.2 前期准备 软件安装 yum install -y epel-release yum install -y certbot 创建目录及链接 方法1 ...
- javaWeb项目(SSH框架+AJAX+百度地图API+Oracle数据库+MyEclipse+Tomcat)之二 基础Hibernate框架搭建篇
我们在搭建完Struts框架之后,从前台想后端传送数据就显得非常简单了.Struts的功能不仅仅是一个拦截器,这只是它的核心功能,此外我们也可以自定义拦截器,和通过注解的方式来更加的简化代码. 接下来 ...
- LeetCode 322. Coin Change
原题 You are given coins of different denominations and a total amount of money amount. Write a functi ...
- checkbox的选中、全选、返选、获取所有选中的值、所有的值、单选全部时父选中
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 【原创】bootstrap框架的学习 第五课
一.Bootstrap 中定义了所有的 HTML 标题(h1 到 h6)的样式. <!DOCTYPE html> <html> <head> <title&g ...
- 【国家集训队2012】tree(伍一鸣)
Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 ...
- [PHP] 网盘搜索引擎-采集爬取百度网盘分享文件实现网盘搜索
标题起的太大了,都是骗人的.最近使用PHP实现了简单的网盘搜索程序,并且关联了微信公众平台.用户可以通过公众号输入关键字,公众号会返回相应的网盘下载地址.就是这么一个简单的功能,类似很多的网盘搜索类网 ...
- python3 selenium 鼠标悬停操作
使用场景: 测试过程中有些元素隐藏在某些元素下面,需要鼠标悬停,才会看到 使用方法: # 定位元素hover_element = driver.find_element_by_css_selector ...
- openresty源码剖析——lua代码的执行
上一篇文章中我们讨论了openresty是如何加载lua代码的 那么加载完成之后的lua代码又是如何执行的呢 ##代码的执行 在init_by_lua等阶段 openresty是在主协程中通过lu ...
- 学习笔记:javascript body常用事件
Window 事件属性 针对 window 对象触发的事件(应用到 <body> 标签): 属性 值 描述 onafterprint script 文档打印之后运行的脚本. onbefor ...