高级BASH
Bash介绍与入门
1,简介
Bash(GNU Bourne-Again Shell)是一个为GNU计划编写的Unix shell,它是许多Linux平台默认使用的shell
shell是一个命令解释器,是结余操作系统内核与用户之间的一个绝缘层。
2,为什么学Bash
对于任何想适当精通一下系统管理知识的人来说,掌握shell脚步知识都是最基本的。
3,初步练习
(1)Hello World
(2)使用脚步清除/var/log下的log文件
查看/var/log下的log文件,并创建新的脚本
代码:
实验机有点差别,有权限,不给删除
Bash的特殊字符(上)
一、#符号
1.#注释
行首以#开头(除#!之外)的是注释。#!是用于指定当前脚本的解释器,我们这里为bash,且应该指明完整路径,所以为/bin/bash
代码:
结果:
二、分号(;)
1.命令分隔符
使用分号(;)可以在同一行上写两个或两个以上的命令
输入代码:
执行脚本:
2.终止case选项(双分号)
使用双分号(;;)可以终止case选项
输入代码
执行脚本:
上面脚本使用case语句,首先创建了一个变量初始化为b,然后使用case语句判断该变量的范围,并打印相关信息。
三,点号(.)
1.等价于source命令
bash中的source命令用于当前bash环境下读取并执行FileName.sh中的命令
四,引号
1,双引号(“)
“STRING”将阻止(解释)STRING中大部分特殊的字符。
2,单引号(‘)
’STRING‘将会阻止STRING中所有特殊字符的解释,这是一种比使用“更强烈的形式。
五,斜线和反斜线
1,斜线(/)
文件名路径分隔符。分隔文件名不同的部分
(如/home/bozo/projects/Makefile)。也可以用来作为除法算数操作符
2,反斜线(\)
一种对单字符的引用机制。\X将会“转义”字符X。这等价于“X",也等价于'X'。\通常用来转义双引号(“)和单引号(’),这样双引号和单引号就不会被解释成特殊含义
六,反引号(`)
1,命令替换
command结构可以将命令的输出赋值到一个变量中去。在后边的后置引用(backquotes)或后置标记(backticks)中也会讲解。
反引号中的命令会优先执行,如:
先创建了back目录,然后赋值test.sh到back目录
七,冒号(:)
1,空命令
等价于“NOP”(no op,一个什么也不干的命令)。也可以被认为与shell的内建命令true作业相同。“:”命令是一个bash的内建命令,它的退出码(exit status)是(0)。
如
等价于
可以在if/then中作占位符
2.变量扩展/子串
在与>重定向操作符结合使用时,将会把一个文件清空,但是并不会修改这个文件的权限。如果之前这个文件并不存在,那么就创建这个文件。
在与>>重定向操作符结合使用时,将不会对预先存在的目标文件(:>>target_file)产生任何影响。如果这个文件之前并不存在,那么就创建它。
也可能用来作为注释行,但不推荐这么做。使用#来注释的话,将关闭剩余行的错误检查,所以可以在注释行中写任何东西。然而,使用的话将不会这样做。如:
“:”还用来在/etc/passwd和¥PATH变量中做分隔符,如:
八,问号(?)
1,测试操作符
在一个双括号结果中,?就是C语言的三元操作符,如:
代码:
运行测试:
九,美元符号
1,变量替换
命令:
测试运行:
2,命令替换(同反引号)
Bash中的特殊字符(下)
一,小括号(())
1,命令组
在括号中的命令列表,将会作为一个子shell来运行
在括号中的变量,由于是在子shell中,所以对于脚本剩下的部分是不可用的。父进程,也就是脚本本身,将不能够读取在子进程中创建的变量,也就是在子shell中创建的变量。如:
运行代码
在圆括号中a变量,更像是一个局部变量
2,初始化数组
创建数组
输入代码:
运行结果
二,大括号
1,文件名扩展
复制t.txt的内容到t.back中
注意:大括号中,不允许有空白,除非这个空白被应用或转义。
2,代码块
代码块,又被称为内部组,这个结果事实上创建了一个匿名函数(一个没有名字的函数)。然而,与“标准”函数不同的是,在其中声明的变量,对于脚本其他部分的代码来说还是说可见的。
三,中括号([])
1,条件测试
条件测试表达式在[ ]中。值得注意的是[是shell内建test命令的一部分,并不是/usr/bin/test中的外部命令的一个链接。下列练习中的-lt(less than)表示小于号
双中括号中([[ ]])也用作条件测试(判断)
2,数组元素
在一个array结构的上下文中,中括号用来引用数组中每个元素的编号
四,尖括号(<和>)
1,重定向
test.sh > filename重定向test.sh的输出到文件filename中。如果filename存在的话,那么将会被覆盖。
test.sh &> filename重定向test.sh的stdout(标志输出)和stderr(标准错误)到filename中
test.sh >&2重定向到test.sh的stdout到stderr中
test.sh >> filename把test.sh的输出追加到文件filename中。如果filename不存在的话,将会被创建。
五,竖线(| )
管道
分析前边命令的输出,并将输出作为后边命令的输入。这是一种产生命令链的好方法
输出的内容均变为了大写字母
六,破折号( - )
1,选项,前缀
在所有的命令内如果想使用选项参数的话,前边都要加上“-”
2,用于重定向stdin或stdout
下面的脚本用于备份最后24小时当前目录下所有修改的文件
七,波浪号(~)
1,目录
~表示home目录
变量和参数
一,变量替换
1.概念
变量的名字就是变量保存值得地方。引用变量的值就叫做变量替换。
如果variable是一个变量的名字,那么$variable就是引用这变量的值,即这变量所包含的数据
$variable事实上只是${variable}的简写形式。在某些上下文中$variable可能会引起错误,这时候你就需要用${variable}了。
2.举例
结果:
二,变量赋值
1,说明
赋值操作前后都不能有空白
因为 = 和 -eq 都可以用做条件测试操作,所以不要与这里的赋值操作相混淆
注意:=既可以用做条件测试操作,也可以用于赋值操作,这需要视具体的上下文而定。bash中==也可作为条件判断。
运行结果
三,变量不区分类型
1,说明
与大多数编译型语言不同,Bahs并不区分变量的“类型”。本质上Bash变量都是字符串。但是依赖于具体的上下文,Bahs也允许比较和整数操作。其中的关键因素就是,为变量赋的值是否只有数字
2,举例:
运行结果:
四,特殊变量
1,局部变量
这种变量只有在代码块或函数中才可见。
2,环境变量
这种变量将影响用户接口和shell的行为
在通常情况下,每个进程都有自己的"环境“,这个环境是由一组变量组成的,这些变量中存在进程可能需要引用的信息。在这种情况下,shell与一个一般的进程没什么区别。
3,位置参数
从命令行传递到脚本的参数:$0,$1,$2,$3...
$0就是脚本文件自身的名字,$1是第一个参数,$2是第二个参数,$3是第三个参数,然后是第四个。$9之后的位置参数就必须用大括号括起来了,比如,${10},${11},${12}。
两个比较特殊的变量$*和$@表示所有位置参数
4,位置参数实例
引用和转义
一,引用变量
1,介绍
在一个双引号中通过直接使用变量名的方法来引用变量,一般情况下都是没问题的。这么做将阻止所有在引号中的特殊字符被重新解释(即都被当做普通的字符串),包括变量名,但是$,`(后置引用)和“\"(转义符)除外。
保留$作为特殊字符的意义是为了能够在双引号中也能够正常的引用变量(“$variable")。
使用双引号还能够阻止单词分割,即使这个参数包含空白,单词也不会被分隔开。如variable1="a variable containing five words"
2,举例
在echo语句中,只有在单词分割或者保留空白的时候,才需要把参数用双引号括起来。
运行结果:
IFS(Internal Field Seperator)在Linux的shell中的预设的分隔符。
IFS是shell脚本中的一个重要概念,在处理文本数据时,它是相当有用的。内部字段分隔符是用于特定用途的定界符。IFS是存储定界符的环境变量,它是当前shell环境使用的默认定界字符串
单引号(‘ ’)操作与双引号基本一样,但是不允许引用变量,因为$的特殊意义将被关闭。
在单引号中,任何特殊字符都按照字面的意识进行解释,除了单引号本身。所以说单引号(全引用)是一种比双引号(部分引用)更严格的引用方法
二,转义
1,概念
转义是一种引用单个字符的方法。一个签名放上转义符(\)的字符就是告诉shell这个字符按照字面的意思进行解释,换句话说,就是这个字符失去了它的特殊含义。
2,转义符的含义
在echo命令中:
\$表示$本身字面的含义(跟在\$后边的变量名将不能引用变量的值),如:
\\表示反斜杠线字面的意思,如:
3,一个实例
运行结果
4,转义符(\)的行为探究
\ 的行为依赖于它自身是否被转义,被引用(“”),或者是否会出现在命令替换或here document中。
举例:
运行结果:
5,变量中的转义
赋值给变量的字符串的元素也会被转义,但是不能把一个单独的转义符赋值给变量
6,转义空格
转移一个空格会阻止命令行参数列表的“单词分割”问题
运行结果:
7,续行功能
转义符也提供续行功能,也就是编写多行命令的功能
每个单词行都包含一个不同的命令,但是每行结尾的转义符都会转义换行符,这样下一行会与上一行一起形成一个命令序列。
运行结果:
如果一个脚本以 | (管道符)结束,那么就不同非的加上转义符( \ )了。但是一个好的编程风格,还是应该在行尾加上转义符。
退出和退出状态码
一,退出状态码
1,退出
exit被用来结束一个脚本,它返回一个值,并且这个值会传递给脚本的父进程,父进程会使用一个值做下一步的处理。
2,退出状态码
每个命令都会返回一个退出状态码(有时候也被称为返回状态)。
成功的命令放回0,不成功的命令放回非零值,非零值通常都被解释成一个错误码。行为良好的UNIX命令、程序和工具都会返回0作为退出码来表示成功,虽然偶尔也会有例外。
同样的,脚本中的函数和脚本本身也会返回退出状态码。在脚本或者是脚本函数中执行的最后的命令会决定退出状态码。在脚本中,exit nnn命令将会nnn退出码递给shell(nnn必须是十进制数,范围必须是0-255)
当脚本以不带参数的exit命令来结束时,脚本的退出状态码就由脚本中最后执行的命令来决定(就是exit之前的命令)。
3,一个例子
$?指代的是上一条指令的执行结果
不带参数的exit命令与exit $? 的效果是一样的,甚至脚本的结尾不写exit也与前两者的效果相同。
二,反转一个条件的用法
1,例子
! 逻辑 “非”操作符,将会反转命令或条件测试的结果,并且这会影响退出状态码。
运行结果:
特定的退出状态码具有保留含义,所以用户不应该在脚本中指定它。
条件判断
一,条件测试结构
1,if/then结构
if/then结构用来判断命令列表的退出状态符是否为0,0表示成功,如果成功的话,就执行接下来的一个或多个命令
注意:这里与C语言等其他语言不同,不能直接使用0或者1作为判断条件,而应该以false,true代替。与其他大多数语言相反的true返回的是0,false返回的是1.
有一个专有命令 [ (左中括号,特殊字符),这个命令与test命令等价,由于效率上的考虑,bash将它作为一个内建命令。
注意:由于Bash的语法检查机制的原因,如果在条件测试时只使用一个[会出现一个错误提示,为了避免这个问题,我们通常将使用一对方括号包含条件测试[]
在版本2.02的Bash中,引入了“[[...]]”扩展测试命令,[[是一个关键字,并不是一个命令。
if命令能够测试任何命令,并不仅仅是中括号中的条件。
2,多级比较(应注意与嵌套条件分支区分)
运行结果:
注意:((...))和let..如果运算结果为非0,该语句退出码为0,否则为1;[[...]]是作为一个单独的语句并且会返回一个退出码
3,真假判断
4,(( ))结构
(( )) 结构扩展并计算一个算术表达式的值。如果表达式的结果为0,那么返回的退出状态符为1,或者是“假”。而一个非零值得表达式所返回的退出状态码为0,或者是“true”。
二,文件测试操作符
1,操作符列举
举例:
三,二元比较操作符
1,整数比较
-eq 等于
if [ "$a" -eq "$b" ]
-ne 不等于
if [ "$a" -ne "$b"]
-gt 大于
if [ "$a -gt "$b"]
-ge 大于等于
if [ "$a" -ge "$b"]
-lt 小于
if [ "$a -lt "$b" ]
-le 小于等于
if [ "$a -le "$b"]
< 小于(在双括号中使用)
(( "$a" < " $b"))
<=小于等于(在双括号中使用)
(( "$a" <= "$b"))
> (在双括号中使用)
(( "$a > "$b" ))
=>(在双括号中使用)
(( "$a" => "$b"))
2,字符串比较
=等于
if [ "$a" = "$b"]
= =等于, 与= 等价
if [ "$a" == "$b" ]
< 小于,按照ASCII字符进行排序
if [ "$a" < "$b"]]
if [ "$a" \< "$b"]]
注意“<”使用在[]结构中的时候需要被转义
大于,按照ASCII字符进行排序
if [[ "$a" > "$b" ]]
if [[ "$a" \> “$b"]]
-z字符串为“null”,意思就是字符串长度为零-n字符串不为“null"
3,算术比较与字符串比较
4,检查字符串是否为null
运行结果:
5,zmore
6.compound和comparison
-a逻辑与exp1 -a exp2 如果表达式exp1和exp2都为真的话那么结果为真。
-o逻辑或exp1 -o exp2 如果表达式exp1和exp2中至少有一个为真的话,那么结果为真。
注意:这与Bash中的比较操作符&&和||非常相像,但是这两个操作符是用在双中括号中的。
[[ condition1 && condition2 ]]
-o 和 -a 操作符一般都是和test命令或者是单中括号结构一起使用的
if [ "$exp1" -a "exp2" ]
操作符
一,赋值
1,变量赋值
= 通用赋值操作符,可用于算术和字符串赋值。
var=27
vategory=minerals #在“="之后是不允许出现空白字符的。
不要混淆=赋值操作与=测试操作符。也正是因为这一点,在bash里面测试操作也常写作==,但这可能在其他shell中是不允许的
----------------------------------------------------------------------
# = 在这里是测试操作符
if [ "$string1" = "$string2" ]
# if [ "X$string1" = "X$string2" ] 是一种更安全的做法
#这样可以防止两个变量中的一个为空所产生的错误
# ( 字符“X”作为前缀在等式两边是可以互相抵消的。)
then
command
fi
---------------------------------------------------------------------------
二,算术操作符
1,简单算术操作符
2,求最大公约数
高级BASH的更多相关文章
- 高级Bash脚本编程指南(27):文本处理命令(三)
高级Bash脚本编程指南(27):文本处理命令(三) 成于坚持,败于止步 处理文本和文本文件的命令 tr 字符转换过滤器. 必须使用引用或中括号, 这样做才是合理的. 引用可以阻止shell重新解释出 ...
- 高级Bash脚本编程指南《Advanced Bash-Scripting Guide》 in Chinese
<Advanced Bash-Scripting Guide> in Chinese <高级Bash脚本编程指南>Revision 10中文版 在线阅读链接:http://ww ...
- abc高级bash shell编程
http://www.pythoner.com/122.html abc高级bash shell编程
- 高级bash脚本编程(三)
高级bash脚本编程 知识点 compound 和 comparison -a 逻辑与 exp1 -a exp2 如果表达式 exp1 和 exp2 都为真的话,那么结果为真. -o 逻辑或 exp1 ...
- 高级Bash脚本编程(二)
高级Bash脚本编程(二) 退出 退出状态码 退出:exit 被用来结束一个脚本,它也返回一个值,并且这个值会传递给脚本的父进程,父进程会使用这个值做下一步的处理. 每个命令都会返回一个退出状态码,成 ...
- 高级Bash脚本编程(一)
高级Bash脚本编程 Bash 它是能力很强的计算机语言,被称为解释性语言或脚本语言,它可以调用所有的UNIX命令和工具再加上公共程序. Bash中的特殊字符 注释(#) (除#!外,#!是用于指定当 ...
- advanced base-scripting guide in chinese(高级Bash脚本编程指南-10)
<高级Bash脚本编程指南>Revision 10中文版 github上链接地址: https://github.com/LinuxStory/Advanced-Bash-Scriptin ...
- 《Advanced Bash-Scripting Guide》 in Chinese 高级Bash脚本编程指南》Revision 10中文版
<Advanced Bash-Scripting Guide> in Chinese <高级Bash脚本编程指南>Revision 10中文版 在线阅读链接:http://ww ...
- 高级Bash Scripting系列笔记--01之“什么情况不适用Bash Script”
1. 占用资源的任务,尤其那些影响速度的工作 比如排序,哈希,递归等等. 2. 大量使用数学运算 尤其是浮点运算,比如任意精度的计算或者复数计算等等,这类使用C++会好很多. 3. 跨平台的(适用 ...
- 脚本命令高级Bash脚本编程指南(31):数学计算命令
题记:写这篇博客要主是加深自己对脚本命令的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢. 高等Bash脚本编程指南(31):数学盘算命令 成于坚持,败于止步 操作数字 factor ...
随机推荐
- 为什么second是秒也是第二?
起源 早期在西方,一小时分为 60 分钟.后来,科学发达了.文明进步了,人们认为一分钟太粗放了.必须划分得更细致,于是就把一分钟划分成 60 等分.由于是对时间的第二次划分,就将新的 60 等分的“单 ...
- SpringBoot2.2发行版新特性
Spring Framework升级 SpringBoot2.2的底层Spring Framework版本升级为5.2. JMX默认禁用 默认情况下不再启用JMX. 可以使用配置属性spring.jm ...
- python调用Opencv库和dlib库
python是一门胶水语言,可以调用C++编译好的dll库 python调用opencv-imggui.dll文件 https://www.cnblogs.com/zhangxian/articles ...
- 用smtplib来发送邮件
先安装 pip install smtplib 发送qq,163邮件,带有附件的邮件 1.qq邮件 # 用于发送邮件的模块import smtplib # QQ邮箱/163邮箱的邮件发送:py文件发送 ...
- Redis缓存雪崩和缓存穿透等问题
穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透. 解决办法:①用一个bitma ...
- 域名、主机名与URL
什么是域名? google.com.baidu.com.163.com等. 域名.主机名与URL例子 例子1: http://mail.163.com/index.html 1)http://:这个是 ...
- 实现Callable接口,并与Future结合使用
实现步骤: 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值. 创建 Callable 实现类的实例,使用 FutureTask ...
- 前台ajax传数组,后台java接收
后端 //添加 @RequestMapping(value = "checkChoise") @ResponseBody ResultJson checkChoise(@Reque ...
- java中异常以及处理异常
一.异常简介 什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错.在java中,阻止当前方法或作用域的情况,称之为异常. java中异常的体系是怎么样的呢? 1.Java中的所有不正常类都 ...
- React Router学习笔记(转自阮一峰老师博客)
React Router是一个路由库,通过管理URL来实现组件切换和状态转变. 1.安装和使用 $ npm install -S react-router 在使用时,作为React组件导入 impor ...