··········1.有哪些编程语言?
1.机器语言 0 和1 构成
2.汇编语言
3.高级语言 c java shell phy 等都是高级语言
编译型: 编译 -》 翻译 -》 计算机 跨平台性差 执行速度快 C C++
解释型: 解释性 -》解释器 -》翻译 -》计算机 跨平台性强 执行速度慢 Shell Python PHP ruby
汇编语言: 优点是比较底层,速度最快,缺点是最复杂,开发效率最低
高级语言: 编译型语言执行速度快,不依赖语言环境运行,跨平台差
解释型语言跨平台好,一份代码,到处使用,缺点是执行速度慢,依赖解释器运行
··········2.Shell如何执行用户的指令?
Shell有两种执行指令的方式
1.第一种方法是用户事先编写一个sh脚本文件,内含Shell脚本,而后使用Shell程序执行该脚本,这种习惯称为 Shell编程;
2.第二种是用户直接在Shell界面上执行Shell命令,由于Shell界面的关系,大家习惯一行一行的书写,很少写出成套的程序一起执行,所有也称为命令行;
总结:
Shell只是为用户与机器之间搭建建成的一个桥梁,让我们能够通过Shell来对计算机进行操作和交互。从而让计算机为我们服务的目的。
··········3.Shell分类
Linux默认的Shell是 /bin/bash
流行的Shell有ash,bash,ksh,csh,zsh等,不同的Shell都有自己的特点以及用途
1./bin/bash
2.csh
c Shell 使用的是类"c"语法,是具有c语言风格的一种Shell,其内部命令有52个,较为庞大,目前使用的并不多,已经被/bin/tcsh所取代
3.ksh
Korn Shell的语法与Bourne Shell相同,同时具备了C Shell的易用特点,许多安装脚本都使用Ksh,ksh有42条内部命令,与bash相比有一定的限制性。
4.tcsh
tcsh是csh的增强版,与C Shell完全兼容
5.sh
是一个快捷方式,已经被/bin/bash所取代
6.nologin
指用户不能登录
7.zsh
目前Linux里面最庞大的一种 zsh. 它有84个内部命令,使用起来也比较复杂,一般情况下,不会使用该Shell
4. bash一些基础特性(自动补全,历史记忆,别名)
·····4.1 bash-complete自动补全脚本
自动补全脚本 bash-completion
如果没有就使用下面命令安装
yum install -y bash-completion
默认情况下,bash为linux用户提供了以下补齐功能
1.变量补全
2.用户名补全
3.主机名补全
4.路径补全
5.文件名补全
·····4.2 history命令历史记忆功能
Bash有自动记录命令的功能,自动记录到.bash_history隐藏文件中,还可以在下次需要直接调用历史记录中的命令
1.查询之前使用的所有命令
history
history n
3.删除相应的第n个命令
history -d n
4.指定执行命令历史中的第N条语句
5.指定执行命令历史中的倒数第N条语句
! -n
6.指定执行命令历史中的最后一条语句
!!
7.指定执行命令历史中的最近一条以[String]开头的语句
![String]
8.将命令历史写入命令历史的文件中
history -w
9.回显 echo 之后的语句,而使用 echo $FILENAME 命令可以查看file所在路径
echo $filename
10.查看命令历史的内容
cat ~/.bash_history
11.删除所有的命令历史记录
history -c
·····4.3 alias别名功能
alias命令,别名的好处是可以把本来很长的指令简化缩写,来提高工作效率;
alias #查看当前系统所有的别名
alias bd=‘curl www.baidu.com’
#定义新的别名,这时候输入h5就等于输入 ‘curl www.baidu.com’
unalias bd #取消别名定义
如果想要文件永久生效,只需将上述别名命令写到对应用户或者系统bashrc文件中
注意,不管修改了什么系统配置文件,记得 source 刷新以下
这里是 source ~/.bashrc
如果想要真实命令可以在命令前面添加反斜杠,使别名失效
··········5.Shell环境变量
bash的初始化
1. /etc/profile 全局(公有)配置,不管是哪个用户,登录时都会读取该配置文件
2. /ect/bashrc
全局,使用脚本时会读取该配置,这个只是在centos系统中才有,在Ubuntu就没有
在Ubuntu里面与之对应的是/etc/bash.bashrc
bash执行时,不管是何种方式,都会读取此文件
3.~/.profile
若bash是以login方式执行时,读取/.bash_profile,若它不存在,则读取/.bash_login,若它不存在,则
读取~/.profile
图像模式登陆时,此文件将会被读取,即使存在/.bash_profile和/.bash_login
4.~/bash_login
若bash是以login方式执行时,读取/.bash_profile,若它不存在,则读取/.bash_login,若前两者不存在,
则读取~/.profile
5.~/.bash_profile
Unbutu默认没此文件,可新建;只有bash是以login形式执行时,才会读取此文件,通常该配置会取读~/.bashrc
6.~/.bashrc
当bash是以non-login 形式执行时,读取此文件,若是以login形式执行,则不会读取此文件;
-
/etc/profile
-
/etc/bashrc
-
~/.profile
-
~/.bash_login
-
~/.bash_profile
-
~/.bashrc
- ~/.bash_logout
图形化界面时 1 3
图形化界面后,打开终端时: 2 6
文件界面时: 2 1 6
su: 2 1 5
2 6
··········6.Shell特性
6.1 快捷键
ctrl+A
把光标移动到命令行开头,如果我们输入的命令过长,想要把光标移动到命令行开头时使用;
ctrl+E
把光标移动到命令行结尾
ctrl+C
强制终止命令
ctrl+L
清屏,相当于clear命令
ctrl+U
删除或剪切光标之前的命令;我输入了一行很长的命令,不用使用退格健一个一个字符的删除,
使用这个快捷键会更加方便
ctrl+K
删除或剪贴光标之后的内容
ctrl+Y
粘贴 ctrl+U或ctrl+K剪贴的内容
ctrl+R
在历史命令中搜索,按下ctrl+R之后,就会出现搜索界面,只要输入搜索内容,就会从历史命令中搜索
ctrl+D
退出当前终端
ctrl+Z
暂停,并放入后台,这个快捷键牵扯工作管理的内容,我们在系统管理章节详细介绍。
ctrl+S
暂停屏幕输出
ctrl+Q
恢复屏幕输出
小火车快捷键
安装 yum -y install sl 输入sl就可以看到了
6.2 前后作业命令
几个常用的作业命令
command & 直接让作业进入后台运行 比如 sl & 就是让小火车后台运行
ctrl+z 将当前作业切换到后台
jobs 查看后台作业状态
fg %n 让后台运行的作业n切换到前台来
bg %n 让指定的作业n在后台运行
kill %n 移除指定的作业n
“n"为jobs命令查看到的jobs编号,不是进程Id
每一个job会有一个对应的job编号,编号从当前的终端从1开始分配
job编号的使用样式为[n],后面可能会跟有”+“号或者”-"号,或者什么也不跟。
"+"号表示最近的一个job
"-"号表示倒数第二个被执行的job
注: "+“号与”-"号会随着作业的完成或添加而动态的发生变化
通过jobs方式来管理作业,当前终端的作业在其他终端不可见
6.3 输入输出重定向
一般情况下:
输入方向就是数据从哪里流向程序。数据默认从键盘流向程序,如果改变了他的方向,数据就从让其他地方流入,这就是输入重定向;
输出方向就是数据从程序流向哪里。数据默认从程序流向显示屏,如果改变了它的方向,数据就流向其他地方,这就是输出重定向;
Linux中一切皆文件,包括标准输入设备(键盘)和标准输出设备(显示器)在内的所有计算机硬件都是文件;
为了表示和区分已经打开的文件,Linux会给每一个文件分配一个ID,这个ID就是一个整数,被称为文件描述符;
输出重定向是指命令的结果不再输出到显示屏上,而是输出到其他地方,一般是文件中,这样做的最大好处就是
把命令的结果保存起来,当我们需要的时候可以随时查询.Bash支持的输出重定向符号如下表所示:
1.标准输出重定向 command > file
作用: 以覆盖的方式,把command的正确输出结果输出到file文件中;
command >>file
作用: 以追加的方式,把command的正确输出结果输出到file文件中
2.标准错误输出重定向 command 2> file
作用: 以覆盖的方式,把command的错误信息输出到file文件中
command 2>>file
作用: 以追加的方式,把command的错误信息输出到file文件中
3.正确输出和错误信息同时保存 command> file 2>&1
作用: 以覆盖的方式,把正确输出和错误信息同时保存到同一个文件file中
command >>file 2>&1
作用: 以追加的方式,把正确输出和错误信息同时保存到同一个文件file中
注意: 输出重定向中 > 代表的是覆盖, >>代表的是追加
输出重定向的完整写法其实是 fd>file 或者 fd>>file ,其中 fd表示文件描述符,如果不写,默认为1,也就是标准输出文件。
当文件描述符为1时,一般省略不写,如上表所示,当然,如果你愿意,
也可以将command >file写作command 1>file,但这样做是多此一举
当文件描述符大于1的值时,比如2,就必须写上。
需要重点说明的是,fd和>之间不能有空格,否则Shell会解析失败; >和file之间的空格可有可无。
为了保持一致,习惯在>两边都不加空格.
ls / &>/dev/null 解释: & 代表正确和错误都包含 /dev/null相当于linux的垃圾回收器,无穷大
输入重定向就是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件作为命令的输入。
command <file 将file文件中的内容作为command的输入
command <<END 从标准输入(键盘)中读取数据,知道遇见分界符END才停止(分界符可以是任意的字符串,用户自己定义).
command file2 将file1作为command的输入,并将command的处理结果输出到file2.
举例: wc -l filename 统计文件的行数
wc -l << END wc命令会一直等待输入,直到遇见分节符为止,这里是END
从文件输入
几个基本符号以及其含义
/dev/null表示空设备文件,相当于window里面的垃圾箱,无穷大
0表示stdin标准输入
1表示stdout标准输出
2表示stderr标准错误
默认为标准输出重定向 与1>相同
2>&1 意思是把标准错误输出,重定向到标准输出
&>file 意思是把标准输出和标准错误输出都重定向到文件file中
&file意思是把标准输出和标准错误输出都重定向到文件file中
/dev/null
如果不想把命令的输出结果保存到文件,也不想把命令的输出结果显示在屏幕上,干扰命令的执行,可以把命令的所有结果重定向到/dev/null文件中
ls -l &>/dev/null
可以把/dev/null当成Linux系统的垃圾箱,任何放入垃圾箱的数据都会被丢弃,不能恢复
6.4 tee管道
1.管道|
管道,从一头进去,从另外一头出来。
在Shell中,管道将一个程序的标准输出作为另外一个程序的标准输入,就像用一根管子将一个程序的输入连接到另外一个程序的输入一样;
管道的符号是|,下面的程序将man的标准输出作为less的标准输入,以实现翻页的功能
man ls | less
2.tee
有时候我们想要同时将程序输出显示在屏幕上(或进入管道)和保存到文件中,这个时候可以使用tee
tee程序的输出和它的输入一样,但是会将输入内容额外的保存到文件中;
cat /etc/passwoed |tee hello.txt
tee程序将cat程序的输出显示在屏幕上,并且在hello.txt文件中保留了副本,需要注意的是,如果tee命令中指定的文件已经存在,那么它将会被覆盖,使用 -a选项在文件末尾追加内容(而不是覆盖)
cat /etc/passwoed |tee -a hello.txt
6.5 命令排序
&& || 具备逻辑判断
&& command1 && command2 当命令1执行成功了才会执行命令2
|| command1 || command2
如果命令1成功就直接打印出来,如果命令1失败了才会执行命令2
常用于:当执行某个命令失败时就安装该命令
; (分号)不具备逻辑判断,其实就是连接2条执行的命令,不具备逻辑判断
6.6 通配符
* 匹配0个或多个任意字符
eg: a*b a与b之间可以存在0或多个字符 ab aabb azsb …
? 匹配一个任意字符
eg: a?b a与b之间有且仅存在一个字符 a1b adb …
[list] 匹配list中的任意单个字符
eg: a[xyz]b a与b之间必须但也只能存在一个字符,该字符只能是x或y或z 例如: axb ayb azb
[!list] 匹配除list中的任意单个字符
eg: a[!a-z]b a与b之间必须但只能存在单个字符,且这个字符不可以是小写字母 列如: aAb
[c1-c2] 匹配c1-c2之间的任意单个字符
eg: a[0-1]b a与b之间必须但只能存在一个字符,该字符只能是数字 列如: a0b a1b
{string1,string2,string3} 匹配string1,string2等中的一个字符串
eg: a{abc,xyz,opq} a与b之间必须但只能存在一个字符串,该字符串只能是abc,xyz,opq
··········7.Shell特性
7.1 代码风格规范
开头有"蛇棒"所谓shebang其实就是在很多脚本的第一行出现的以"#!"开头的注释,它指明了当我们没指定解释器的时候默认的解释器,一般有以下几种:
#! /bin/sh
#! /bin/bash 等等
直接使用./a.sh来执行脚本的时候,如果没用shebang,就会默认用$shell指定的解释器,否则就会用shebang指定的解释器。也可以用下面的方式来指定
#! /usr/bin/env bash
7.2 代码要有注释
注释,显然是一个常识,不过这里还是要再强调一下,这个在shell脚本里尤为重要。因为很多单行的shell命令不是那么浅显易懂,没有注释的话在维护起来会让人尤其的头大。
注释的意义不仅在于解释用途,而在于告诉我们注意事项,就像是一个README。
具体的来说,对于shell脚本,注释一般包括下面几个部分:
shebang
脚本的参数
脚本的用途
脚本的注意事项
脚本的写作时间,作者,版权等
各个函数前的说明注释
一些较复杂的单行命令注释
7.3 参数要规范
这一点很重要,当我们的脚本需要接受参数的时候,我们一定要先判断参数是否合乎规范,并给出合适的回显,方便使用者了解参数的使用。
最少,最少,我们至少得判断下参数的个数吧:
参数要规范:
if [[$# !=2]];then
echo “Parameter incorrect”
exit 1
fi
7.4 变量
一般情况下我们会将一些重要的环境变量定义在开头,确保这些变量的存在。
source /etc/profile
export PATH=”/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/apps/bin/”
这种定义方式一个很常见的用途,最典型的应用就是,当我们本地安装了很多java版本时,我们可能需要指定一个java来用。那么这时我们就会在脚本开头重新定义JAVA_HOME以及PATH变量来进行控制。
同时,一段好的代码通常是不会有很多硬编码在代码里的“魔数”的。如果一定要有,通常是用一个变量的形式定义在开头,然后调用的时候直接调用这个变量,这样方便日后的修改。
7.5 缩进
7.6 命名有标准
7.7 编码要统一
7.8 权限记得加
7.8.1 chmod a+x
chmod a+x的含义
版权
chmod a+x a.txt 等价于 chmod +x a.txt 给所用户给予a.txt文件可执行权限
chmod u+x a.txt a.txt文件的所有用户可执行权限
chmod g+x a.txt a.txt用户组可执行权限
chmod o+x a.txt a.txt其他用户可执行权限
7.9 日志和回显
7.10 密钥要移除
7.11 太长要分行
7.12 学会查路径
很多情况下,我们会先获取当前脚本的路径,然后一这个路径为基准,去找其他的路径。通常我们是直接用pwd以期获得脚本的路径。
不过其实这样是不严谨的,pwd获得的是当前shell的执行路径,而不是当前脚本的执行路径。
正确的做法应该是下面这两种:
script_dir=$(cd $(dirname KaTeX parse error: Expected 'EOF', got '&' at position 4: 0) &̲& pwd) script_…(dirname $(readlink -f $0 ))
应当先cd进当前脚本的目录然后再pwd,或者直接读取当前脚本的所在路径。
7.13 代码要简短
7.14 代码有效率
在使用命令的时候要了解命令的具体做法,尤其当数据处理量大的时候,要时刻考虑该命令是否会影响效率。
比如下面的两个sed命令:
他们的作用一样,都是获取文件的第一行。但是第一条命令会读取整个文件,而第二条命令只读取第一行。当文件很大的时候,仅仅是这样一条命令不一样就会造成巨大的效率差异。
当然,这里只是为了举一个例子,这个例子真正正确的用法应该是使用 head -n 1 file 命令。。。
勤用双引号
几乎所有的大佬都推荐在使用”$”来获取变量的时候最好加上双引号。
不加上双引号在很多情况下都会造成很大的麻烦,为什么呢?举一个例子:
他的运行结果如下:
为啥会这样呢?其实可以解释为它执行了下面的命令:就是一个是打印出字符串一个是打印出所有脚本
在很多情况下,在将变量作为参数的时候,一定要注意上面这一点,仔细体会其中的差异。上面只是一个非常小的例子,实际应用的时候由于这个细节导致的问题实在是太多了。。。
巧用main函数
我们知道,像java,C这样的编译型语言都会有一个函数入口,这种结构使得代码可读性很强,我们知道哪些直接执行,那些是函数。但是脚本不一样,脚本属于解释性语言,从第一行直接执行到最后一行,如果在这当中命令与函数糅杂在一起,那就非常难读了。
用python的朋友都知道,一个合乎标准的python脚本大体上至少是这样的:
他用一个很巧妙的方法实现了我们习惯的main函数,使得代码可读性更强。
在shell中,我们也有类似的小技巧:
我们可以采用这种写法,同样实现类似的main函数,使得脚本的结构化程度更好。
考虑作用域
shell中默认的变量作用域都是全局的,比如下面的脚本:
他的输出结果就是2而不是1,这样显然不符合我们的编码习惯,很容易造成一些问题。
因此,相比直接使用全局变量,我们最好使用local readonly这类的命令,其次我们可以使用declare来声明变量。这些方式都比使用全局方式定义要好。
巧用heredocs
所谓heredocs,也可以算是一种多行输入的方法,即在”<<”后定一个标识符,接着我们可以输入多行内容,直到再次遇到标识符为止。
使用heredocs,我们可以非常方便的生成一些模板文件:
7.15 使用新的写法
7.16 其他小 Tip
考虑到还有很多零碎的点,就不一一展开了,这里简单提一提。
1.路径尽量保持绝对路径,不容易出错,如果非要用相对路径,最好用./修饰
2.优先使用bash的变量替换代替awk sed,这样更加简短
3.简单的if尽量使用&& ||,写成单行。比如[[ x > 2]] && echo x
4.当export变量时,尽量加上子脚本的namespace,保证变量不冲突
5.会使用trap捕获信号,并在接受到终止信号时执行一些收尾工作
6.使用mktemp生成临时文件或文件夹
7.利用/dev/null过滤不友好的输出信息
8.会利用命令的返回值判断命令的执行情况
9.使用文件前要判断文件是否存在,否则做好异常处理
10.不要处理ls后的数据(比如ls -l | awk ‘{ print $8 }’), ls的结果非常不确定,并且平台有关
11.读取文件时不要使用for loop而要使用while read
··········8.Shell脚本调试
Shell脚本的语法调试,使用bash的相关参数进行调试
sh [参数] 文件名.sh
-n 不要执行script,仅查询语法
-v 在执行script之前,先将script的内容输出到屏幕上
-x 将使用的脚本的内容输出到屏幕,该参数经常被使用
执行脚本有以下方式,使用工作目录方式执行脚本需要加权限 默认开全部权限
除了脚本sh bash 执行以及工作目录执行外,在shell环境下也可以使用shell环境执行
Shell 环境执行
··········9.作业脱机管理nohup
nohup
将作业(进程)切换到后台可以避免由于误操作如[ctrl]+c等导致的job被异常中断的情形,而脱机管理主要是针对终端异常断开的情形。
通常使用nohup命令来使得脱机或注销之后,Job依旧可以继续运行。也就是说nohup忽略所有挂断(SIGHUP)信号。
如果该方式命令之后未指定&符号,则job位于前台,指定&符号,则job位于后台。
下面是使用nohup方式且将Job放入后台处理,同时指定了日志文件,则nohup使用指定的日志文件,
而不会输出到缺省的nohup.out
eg:
启动进程
nohup java -jar babyshark-0.0.1-SNAPSHOT.jar > log.file 2>&1 &
··········10.Screen
官方网址:http://www.gnu.org/software/screen/
1、简介
Screen是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。
在Screen环境下,所有的会话都独立的运行,并拥有各自的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并可以自由的重定向各个窗口的输入和输出。
2、语法
$> screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s ][-S <作业名称>]
-A 将所有的视窗都调整为目前终端机的大小。
-d <作业名称> 将指定的screen作业离线。
-h <行数> 指定视窗的缓冲区行数。
-m 即使目前已在作业中的screen作业,仍强制建立新的screen作业。
-r <作业名称> 恢复离线的screen作业。
-R 先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。
-s 指定建立新视窗时,所要执行的shell。
-v 显示版本信息。
-x 恢复之前离线的screen作业。
-ls或–list 显示目前所有的screen作业。
-wipe 检查目前所有的screen作业,并删除已经无法使用的screen作业。
3、常用screen参数
screen -S yourname -> 新建一个叫yourname的session
screen -ls -> 列出当前所有的session
screen -r yourname -> 回到yourname这个session
screen -d yourname -> 远程detach某个session
screen -d -r yourname -> 结束当前session并回到yourname这个session
4、在Session下,使用ctrl+a(C-a)
C-a ? -> 显示所有键绑定信息
C-a c -> 创建一个新的运行shell的窗口并切换到该窗口
C-a n -> Next,切换到下一个 window
C-a p -> PrevIoUs,切换到前一个 window
C-a 0…9 -> 切换到第 0…9 个 window
Ctrl+a [Space] -> 由视窗0循序切换到视窗9
C-a C-a -> 在两个最近使用的 window 间切换
C-a x -> 锁住当前的 window,需用用户密码解锁
C-a d -> detach,暂时离开当前session,将目前的 screen session (可能含有多个 windows) 丢到后台执行,并会回到还没进 screen 时的状态,此时在 screen session 里,每个 window 内运行的 process (无论是前台/后台)都在继续执行,即使 logout 也不影响。
C-a z -> 把当前session放到后台执行,用 shell 的 fg 命令则可回去。
C-a w -> 显示所有窗口列表
C-a t -> time,显示当前时间,和系统的 load
C-a k -> kill window,强行关闭当前的 window
C-a [ -> 进入 copy mode,在 copy mode 下可以回滚、搜索、复制就像用使用 vi 一样
C-b Backward,PageUp
C-f Forward,PageDown
H(大写) High,将光标移至左上角
L Low,将光标移至左下角
0 移到行首
$ 行末
w forward one word,以字为单位往前移
b backward one word,以字为单位往后移
Space 第一次按为标记区起点,第二次按为终点
Esc 结束 copy mode
C-a ] -> paste,把刚刚在 copy mode 选定的内容贴上
5、常用操作
创建会话(-m 强制):
screen -dmS session_name
session_name session名称
关闭会话:
screen -X -S [session # you want to kill] quit
查看所会话:
screen -ls
进入会话:
screen -r session_name
··········11. shell变量
11.1 自定义变量
自定义变量: 变量名=变量值 变量名必须以字母或下划线开头 区分大小写
查看变量 echo $变量名
取消变量 unset 变量名
作用范围 仅在当前窗口shell中有效
自定义变量abc=aaaabbbcccc
打印变量 echo $abc
也可以打印pwd 只不过需要添加反斜杠
取消自定义变量 unset 变量名
如果新开一个窗口或者取消自定义变量,则失效
11.2 环境变量
环境变量
其实就是 /etc/profile
~/.bashrc 等
11.3 位置变量
定义一个脚本 ,$1 $2 $3
当给3个参数赋值时,会给1 2 3 赋值,但是不足3个,就从上到下赋值,根据顺序赋值而不是数字
11.4 预定义变量
1、$# 表示参数个数。
2、$0 是脚本本身的名字。
3、$1 是传递给该shell脚本的第一个参数。
4、$2 是传递给该shell脚本的第二个参数。
5、$@ 表示所有参数,并且所有参数都是独立的。
6、$$ 是脚本运行的当前进程ID号。
$! 上一个后台进程的PID
7、 $? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误。
8 、 $* 将所有参数作为一个整体
··········12 shell变量赋值方式
1.显示赋值
变量名=变量值
ip1=192.168.1.251
school=“beijing”
today=date +%F
today=$(date +%F)
read 变量名
read -p “提示信息” 变量名
read -t 5 -p “提示信息” 变量名 -t 5 意思是5秒不输入算超时
read -n 2 变量名 -n 代表字符数量 -n 2 代表2个字符
""代表强引用
''代表弱引用
·········· 13 shell变量运算
整数运算
13.1 方法一: expr + - * % 注意空格必须要有
13.2 方法二: $(())
其实就是把expr换成双括号的形式,另外一般搭配echo使用,
直接使用命令是打印不出来的
13.3 方法三: $[] 雷同方法二
13.4 方法四: let
小数运算
echo “2*4”|bc 2乘以4等于8
echo “2^4”|bc 2的四次方等于16
echo “scale=2;6/4” |bc scale的意思是保留小数点2位
awk ‘BEGIN{print 1/2}’
··········14 内容替换与删除
"消除"
索引以及切片
替换
··········15 函数
可以带function fun()定义 ,也可以直接fun() 定义,不带任何参数
#方法一
function name{
commands
[return value]
}
#方法二
name(){
commands
[return value]
}
#方法三
function name{
commands
[return value]
}
function 是shell中的关键字,专门用来定义函数;
name是函数名;
commands是函数要执行的代码
return value表示函数的返回值,其中return 是shell关键字,专门用在函数中返回一个值;
这一部分可以写也可以不写。
由{}包围的部分称为函数体,调用一个函数,实际上就是执行函数体中的代码。
函数的优势
方便n次使用,减少代码量,使之方便,简洁。
当需要修改里面的重复代码时,只需要修改一次函数即可实现需求;
将函数写进文件,需要时直接通过文件调用
执行带参数的函数
functionName arg1 arg2
Shell中的位置参数(1/2…/?/$@)均可作为函数的参数进行传递
@$0比较特殊,仍然是父脚本的名称
此时父脚本的参数会临时被函数的参数所掩盖或隐藏
函数的参数变量是在函数里面进行定义
15.1 参数传递
15.2 return返回函数结果
15.3 从文件中调用函数
15.4 全局变量和局部变量
15.5 数组变量和函数
15.6 递归函数
15.7 for循环语法结构
for循环的语法结构
for 变量 in 值集合
do
执行命令
done
—案列1 创建文件夹----
eg: 因为刚开始不确定是否存在目录所以加-p
for i in {1..10}
do
mkdir -p /datas/demo$i
for o in {1..10}
do
mkdir /datas/demo$i/test$o
done
done
也可以使用下面的方式
eg: 因为刚开始不确定是否存在目录所以加-p
for i in $(seq 1 10)
do
mkdir -p /datas/demo$i
for o in $(seq 1 10)
do
mkdir /datas/demo$i/test$o
done
done
–案列2 计算目录的大小----
15.8 while循环语句结构
while 条件测试
do
执行命令
done
while语法说明,while首先进行条件测试,如果传回值为0(条件测试为真),
则进入循环,执行命令区域,否则不进入循环。
满足while测试条件,执行命令区域,直到while的测试条件不满足结束执行
while循环(如果条件一直满足执行无穷循环)
==实列1:
#! /bin/bash
while read a #使用read有标准输入读取数据,赋值变量demo中,如果读取的数据非空,就进入循环
do ,现实读取到的内容
echo $a
done < /datas/6files
#!/bin/bash
while read demo
do
echo ${demo}
done < /home/srcipts/testfile #将/home/scipts/testfile的内容按行输入给read读取
=实列2:
#! /bin/bash
declare -i i=1 #声明设置i和sum为整数型
declare -i sum=0
while ((i<=10)) #while条件测试,只要i值小于或等于10,就执行循环
do
let sum+=i #sum+=i 和sum=sum +i 是一样的,sum累加i
let i++ #let i++, i的值递增,此行是改变条件测试的命令
done # 遇到done,回到while条件测试
echo $sum # 直到while条件不满足,显示sum的值
15.9 until循环语句
Shell循环until语句
while循环的条件测试是测试真值,until循环则是测试假值
until循环的语法结构
until 条件测试
do
执行命令
done
#!/bin/bash
declare -i i=10 #声明i和sum为整数型
declare -i sum=0
until ((i>10)) #条件测试:只要i值未超过10,就进入循环
do
let sum+=i #sum+=i和sum=sum+i是一样的,sum累加上i
let ++i #i的值递增1,此行是改变条件测试的命令,一旦i大于10,可终止循环
done #遇到done ,回到until条件测试
echo $sum #直到until的条件满足显示sum的值
15.10 Shell循环控制
Shell循环控制
break continue exit 一般用于循环结构中控制循环的走向
break n n表示退出循环的次数,如果省略n表示跳出整个循环
continue n表示退到第n层继续循环,如果省略n表示跳过本次循环进入下一次循环
exit n 退出当前的shell程序,并返回n,n也可以省略
return 用于返回一个退出值给调用的函数
shift 用于将参数列表list左移指定次数,最左端的那个参数就从列表中删除,其后边的参数 进入循环
15.11 Shell测试表达式
15.11.1 test测试表达式
test测试表达式,利用test命令进行条件测试表达式,test命令与测试表达式之间至少有一个空格
[测试表达式] 通过[]中括号进行条件测试表达式,[]中括号边界与测试表达式之间至少有一个空格
[[测试表达式]] 通过[[]]双括号进行条件测试表达式,[[]]双括号与测试表达式之间至少有一个空格
((测试表达式)) 通过(())双小括号进行条件测试表达式,(())双小括号两端不需要空格,常用于整数对比
$[] 整数运算
$() 命令替换 shell会执行括号的cmd,然后将结果作为变量进行替换,替换只能替换标准输出,错误输出不能替换
${} shell中变量的原型,用于限定变量名称的范围,并且支持通配符
[] 条件测试
() 子shell中执行
{} 在当前shell执行
#()是重新开一个子shell然后执行,而{}则是在当前shell里执行
#()最后一个命令可以不用分号,{}最后一个命令要用分号。
#()里第一个命令和左边括号不必有空格,而{}第一个命令和左括号之间必须有一个空格
#()和{}里的某个命令的重定向会影响该命令,而{}里的会影响内外的所有命令
15.11.2 文件测试表达式
linux 下表达式
文件表达式
-e filename 如果 filename文件不管是文件还是目录只要存在,则为真
-d filename 如果 filename文件存在且为目录,则为真
-f filename 如果 filename为常规文件且存在,则为真
-L filename 如果 filename为符号链接,则为真
-r filename 如果 filename文件存在且有可读权限,则为真
-w filename 如果 filename文件存在且有可写权限,则为真
-x filename 如果 filename文件存在且有可执行权限,则为真
-s filename 如果文件文件且文件大小不为0,则为真
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,根据文件的修改之间计算,则为真。
filename1 -ot filename2 如果 filename1比 filename2旧,根据文件的修改之间计算,则为真。
整数变量表达式
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
字符串变量表达式
If [ $a = $b ] 如果string1等于string2,则为真 ,字符串允许使用赋值号做等号
if [ $string1 != $string2 ] 如果string1不等于string2,则为真
if [ -n $string ] 如果string 非空(非0),返回0(true)
if [ -z $string ] 如果string 为空,则为真
if [ $sting ] 如果string 非空,返回0 (和-n类似)
逻辑与-a 条件表达式的并列
if[表达式1 -a 表达式2]
逻辑或-o 条件表达式的或
if[表达式1 -o 表达式2]
15.11.3 字符串测试表达式
字符串测试表达式
参数 功能
-z s1 如果字符串s1的长度为0,则测试条件为真
-n s1 如果字符串s1的长度大于0,则测试条件为真
sl 如果字符串s1不是空字符串,则测试条件为真
=或== s1=s2 如果s1等于s2,则测试条件为真,"="前后应有空格
!= s1!=s2 如果s1不等于s2,则测试条件为真
< s1 如果按照字典顺序s1在s2之前,则测试条件为真
> s1>s2 如果按自定义顺序s1在s2之后,则测试条件为真
注意
对于字符串的比较,一定要将字符串加比引号后再比较,如[ -n “$string”]
=与!=可用于判断两个字符串是否相同
15.11.4 数值测试表达式
整数操作符
在[]和test中使用 在[[]]和(())中使用 说明
-eq ==或= 等于,全拼为equal
-nq != 不等于,全拼为not equal
-gt > 大于,全拼为greater than
-ge >= 大于等于 greater equal
-lt < 小于,全拼为less than
-le <= 小于等于,全拼为 less equal
C语言风格比较
实列:
15.11.5 测试表达式符号
在[]和test中使用 在[[]] 和(())中使用 说明
-a && and ,与,两端都为真,则结果为真
-o || or,或,两端有一个为真,则结果为真
! ! not,非,两端相反,则结果为真
15.12 Shell分支if语句
15.12.1 单If语句
单If分支语句
if <条件表达式>
then
指令f
fi
if <条件表达式>;then
指令f
fi
#简单记忆法:
如果 <你给我足够多的钱>
�
那么
我就给你干活
�
果如
#说明:<条件表达式> 可以是test、[]、[[]]、(())等条件表达式,每一个if条件语句都是以if开头,并带有then,最后以fi结尾
15.12.2 双If语句
if <条件表达式>
then
命令集1
else
命令集2f
fi
#简单记忆
�
如果 <你给我足够多的钱>
�
那么
�
我就给你干活
�
否则
�
我再考虑一下
�
果如
15.12.2 多If语句
if <条件表达式1>
then
指令集1
elif <条件表达式2>
then
指令集2
elif <条件表达式3>
then
指令集3
else
指令集4f
fi
#提示:如果加elif,那么就要加then,每个elif都要带有then,最后结尾的else后面没有then
#简单记忆
如果 <你有房>
那么
我就嫁给你
或者如果 <你家里有钱>
那么
我也可以嫁给你
或者如果 <你很努力很吃苦>
那么
我们可以先谈谈男女朋友
否则
我们没戏
�
果如
15.13 Shell分支case语句
case "变量" in
值1)
指令1...
如果变量的值等于1则执行指令1
;;
值2)
指令2...
如果变量的值等于2则执行指令2
;;
*)
指令3...
如果变量的值不等于以上的任何列值则执行默认指令
esac
#说明:当变量的值等于1时,那么就会相应的执行指令1的相关命令输出,值等于2时就执行指令2的命令,以此类推,如果都不符合的话,则执行*后面的指令,要注意内容的缩进距离
15.14 break语句
15.15 Shell-数组
15.15.1 赋值数组
1.数组的定义
方法一: 用小括号将变量括起来赋值给数组变量,每个变量之间要用空格分隔
方法二: 用小括号将变量值括起来,同时采用键值对的形式赋值
方法三: 通过分别定义数组变量的方法来定义
方法四: 动态地定义数组变量,并使用命令的输出结果作为数组的内容
ps:因为是系统命令,所以要使用转义符号 反斜杠
ps:如果下标存在,会被覆盖原来的值
15.15.2 查数组
${ARRAY_NAME[INDEX]} #引用数组中的元素,注意: 引用时,只给数组名,表示引用下标为0的元素
${#ARRAY_NAME[]} #数组中元素的个数
${#ARRAY_NAME[@]} #数组中元素的个数
${ARRAY_NAME[]} #引用数组中的所有元素
${ARRAY_NAME[@]} #引用数组中的所有元素
${#ARRAY_NAME} #数组中下标为0的字符个数
15.15.3 替换数组
15.15.4 删除数组
因为数组本质上还是变量,因此可以通过"unset"数组[下标]清除相应的数组元素,如果不带下标,表示清除整个数组的所有数据
15.15.5 切割数组
15.15.5 数据分片
格式:
${ARRAY_NAME[@]:offset:number}
15.15.6 遍历数组
遍历数组:
创建一个数组 array=(A B C D 1 2 3 4)
普通for循环
1.标准的for循环
for(( i=0; i<${#array[@]}; i++ ))
do
#${#array[@]} 获取数组长度用于循环
echo ${array[i]}
done
不带索引for循环
for ...in 循环(不带数组下标)
for var in ${array[*]}
do
echo $var
done
while循环
i=0
while [ $i -lt ${#array[@]}]
#当变量(下标)小于数组长度时进入循环体
do
echo ${ array[$i] }
#按下标打印数组元素
let i++
done
15.16 Shell正则表达式
shell 正则表达式
一、正则表达式的概念及特点:
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,
这个“规则字符串”用来表达对字符串的一种过滤逻辑。规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正则表达式(Regular Expression)。给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
- 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
- 可以通过正则表达式,从字符串中获取我们想要的特定部分。
正则表达式的特点:
- 灵活性、逻辑性和功能性非常的强;
- 可以迅速地用极简单的方式达到字符串的复杂控制。
- 对于刚接触的人来说,比较晦涩难懂。
由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器EditPlus,大到Microsoft Word、Visual Studio等大型编辑器,都可以使用正则表达式来处理文本内容。
重要的文本处理工具:
vim sed awk grep
由三部分组成
字符类
数量限定符
位置限定符
15.17 Shell-grep
作为linux中最为常用的三大文本(awk,sed,grep)处理工具之一,
掌握好其用法是很有必要的。
首先谈一下grep命令的常用格式为:grep [选项] ”模式“ [文件1] [文件2]
grep家族总共有三个:grep,egrep,fgrep。
常用项:
-E :开启扩展(Extend)的正则表达式。
-i :忽略大小写(ignore case)。
-v :反过来(invert),只打印没有匹配的,而匹配的反而不打印。
-n :显示行号
-w :被匹配的文本只能是单词,不能是单词中的某一部分,如文本中有liker,但搜寻的只是like,就可以使用-w选项来避免匹配liker
-c :显示总共有多少行被匹配到了,而不是显示被匹配到的内容,注意如果同时使用-cv选项是显示有多少行没有被匹配到。
-o :只显示被模式匹配到的字符串。
--color :将匹配到的内容以颜色高亮显示。
-A n:显示匹配到的字符串所在的行及其后n行,after
-B n:显示匹配到的字符串所在的行及其前n行,before
-C n:显示匹配到的字符串所在的行及其前后各n行,context
1、直接输入要匹配的字符串,这个可以用fgrep(fast grep)代替来提高查找速度.
grep -f 等价于 fgrep
2.扩展的(Extend)正则表达式(注意要使用扩展的正则表达式要加-E选项,或者直接使用egrep)
grep -E 等价于 egrep
实战1:
输出 abc.log文件中 含有从abcd.log文件中读取出的关键词的内容并高亮显示
实战2: 输出以"。"结尾的
实战3: 输出 包含"开启"或者"忽略"的字段
15.18 Shell-sed流编辑器
Linux sed 命令是利用脚本来处理文本文件。
sed 可依照脚本的指令来处理、编辑文本文件。
Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。
语法:
sed [-hnV][-e
参数说明:
-e
-f<script文件>或–file=<script文件> 以选项中指定的script文件来处理输入的文本文件。
-h或–help 显示帮助。
-n或–quiet或–silent 仅显示script处理后的结果。
-V或–version 显示版本信息。
动作说明:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
15.18.1 Shell-sed流编辑器–///或!!!或###替换
可以使用 / / / 也可以使用 ! ! ! 也可以使用 # # #
15.18.2 Shell-sed流编辑器–将替换之后的内容写进文件
15.18.3 Shell-sed流编辑器–正则匹配替换
正则匹配 匹配以Hello开头的将它替换成HHello
15.18.4 Shell-sed流编辑器–使用数字方式进行寻址
15.18.5 Shell-sed流编辑器–加d删除行
15.19 Shell-awk
AWK命令结构
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
15.19.1 Shell-awk-直接命令行调用
Shell脚本中awk指令的用法:
语法格式:awk [选项] ‘指令’ 操作文件
常用项:-F 指定分隔符,分隔符用""引起来
-v:var=value在awk程序开始之前指定一个值valu给变量var,这些变量值用于awk程序的BEGIN快
-f:后面跟一个保存了awk程序的文件,代替在命令行指定awk程序
实例1:在命令行直接输入awk指令:
1. awk ‘{print}’ awk.txt #逐行读取文件awk.txt内容并打印
2. awk ‘{print $0}’ awk.txt #逐行读取文件awk.txt内容并打印改行,$0保存的是当前行的内容
3. awk ‘{print “hello”}’ awk.txt #逐行读取awk.txt文件内容,每行结束后打印一个hello,
文件awk.txt有多少行就打印多少个hello
4.awk ‘{print $1}’ awk.txt #打印awk.txt的第一列内容,在不指定分割符的情况下,awk默认使用空白做分割符
5.awk -F “:” ‘{print $1}’ /etc/passwd #以":"为分隔符打印/etc/passwd文件的第一例内容
15.19.2 Shell-awk-将awk指令写入文件,通过-f选项调用
将awk指令写入文件,通过-f选项调用
vim awkscript
BEGIN{
FS=":"
}
{print $1}
awk -f awkscript /etc/passwd
15.19.3 Shell-awk–begin和end
实例3:awk的BEGIN块和END块
BEGIN用于初始化FS变量(列分隔符),打印标题,或者初始化后需要在程序中调用的全局变量
END用于执行最后的运算或者打印最终的输出结果
END块和BEGIN不是必须的
15.19.4 Shell-awk—在awk中使用正则匹配
实例4:在awk中使用正 则匹配,正则表达式必须要放在//中
- awk ‘/Hello/{print}’ awk.txt #打印awk.txt中匹配Hello的那一行内容
- awk -F “:” ‘/123/{print $2}’ 1.txt
#以":"为分隔符打印1.txt中匹配123的那一行中,第二列的内容
3.awk -F “:” ‘$1 ~ /root/{print $2}’ /etc/passwd
#打印/etc/passwd中,第一列匹配root的行其第二列的内容 ~表示匹配
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。