没看懂从else if 开始的三行是什么意思?

shell学习必备基础
  1. 如何在bash上执行程序
  2. 使用 &将程序放在后台执行

为什么要使用shell脚本?

使用脚本编程语言的好处是,脚本语言多半运行在比编译语言还高得层级,能够轻易处理文件与目录之类的对象.
缺点:一般情况下,效率比较低.不过权衡之下,脚本的执行速度已经很快,快到足以让人感觉不到性能不高了.

shell似乎是不同版本的linux系统之间的通用功能.shell脚本只要用心写,就能应用到很多系统上.

shell脚本的过人之处

简单性:shell是高级语言
可移植性:通过POSIX(可移植操作系统接口,是IEEE为要在各种UNIX操作系统上运行的软件,而定义API的一系列互相关联的标准的总称)所定义的功能,可以在不同的系统上执行,无需需改.
开发容易:短时间即可完成一个功能强大又好用的脚本(字啊以后的学习中就能看到)

who 能看到以下内容

表示系统当前有多少人登陆,登陆用户-使用的终端-登陆时间&登出时间

也可以执行一些独立的程序 比如:#/bin/awk -f

以下是几个初级的陷阱:
1.对#!这一行的长度尽量不要超过64个字符
2.脚本的可移植性取决于是否有完整的路径名称
3.不要在选项之后放置任何空白,因为空白也会跟着选项一起传递给被引用的程序.
4.需要知道解释器的完成路径的名称.这样可以规避可移植性的问题,厂商不同,同样的东西可能放在不同的地方
5.一些较久的系统,内核不具备#!的能力,有些shell会自行处理,这些shell对于#!与紧随其后的解释器名称之间是否可以有空白,可能有不同的解释.

shell识别三种基本命令:

  1. 内建命令:就是linux的命令,例如cd,ls,mkdir等,这些命令是由于其必要性才内建的,内外一种命令的村子啊是为了效率,其中最典型的就是test,
  2. shell函数:功能健全的一系列程序代码,用shell语言写成,可以像使用命令一样使用,就是在C++中调用函数.
  3. 外部命令:是由shell的副本(新的进程)所执行的命令,还是命令.

在shell中,变量值可以是(通常是)空值,也就是不含有任何字符.这是合理的,也是常见的,好用的特性.空值就是null
在shell中变量名的长度无限制,所能保存的字符数同样没有限制.
变量的赋值方式:变量名=值,中间不能有任何的空格,如果想去除shell变量的值时,需要在变量名前加上$字符.当所赋予的值包含空格的时候,需要将值用单引号或者双引号包起来,用单引号包起来的后果是单引号里面的所有特殊符号都不具备特殊含义,用双引号包起来代表特殊符号有特殊含义.

echo的作用就是产生输出,可以提示用户,或者用来产生数据提供用户,或者产生数据进一步处理.

以前的echo只能将参数打印到shell交互界面上,参数之间以一个空格隔开,并以换行符号结尾.
后来又衍生出了-n选项,省略结尾的换行符号.

用途是产生shell脚本的输出,没有什么主要选项.行为模式是将参数打印到标准输出,参数之间用空格隔开,并以换行符结尾.转义序列用来表示特殊字符,以及控制其行为模式.

-n 不要在最后自动换行
-e 若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:

\b #删除前一个字符 \c # 最后不加上换行符号; \f #换行但光标仍旧停留在原来的位置

如同echo命令,printf命令可以输出简单的字符串,但是printf 不提供自动换行

# 单引号与双引号效果一样 # 没有引号也可以输出 # 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用 # 如果以 %d 的格式来显示字符串,那么会有警告,提示无效的数字,此时默认置为 0

在了解重定向之前,需要先了解一下标准的输入输出,总的来说,所有的数据都有来源,也都应该都重点,默认的标准输入输出就是终端.

所谓的I/O重定向就是通过与终端交互,或是在shell脚本里设置,重新安排从哪里输入或者输出到哪里.

< 改变标准输入
> 改变标准输出

重定向符号在目的地文件不存在的时候会新建一个文件,如果存在,则会覆盖!

在构造管道的时候,应该试着让每个阶段的数据量变少,也就是说,把会让数据变少的命令放在前边,提高后面的命令的执行效率.例如,sort之前,先用grep找出相关的行,这样可以让sort少做些事.

当被用作重定向输出时,程序的输出被直接丢弃。该文件用在那些不关心程序输出的地方。
当被用作重定向输入时,输入则是文件结束。
当被用作重定向时,表示重定向到终端。

shell基本命令查找与添加

shell会沿着$PATH来寻找命令.$PATH是一个以冒号分割的目录列表,你可以在列表所指定的目录下找到所要执行的命令.命令可能是shell脚本,也可能是编译后的可执行文件,从用户角度来看,二者并无不同.

默认路径至少包含/bin和/usr/bin,或许还包含其他的.
名称为bin的目录用来保存可执行文件.
如果要编写自己的脚本,最好准备一个自己的bin目录来存放他们,并且让shell能够自动找到他们.
$PATH里的空项目表示当前项目.空项目位于路径中间时,可以用两个连续的冒号来表示,如果将冒号直接置于最前端或尾端,分别表示查找的时候最先查找或最后查找当前目录.

比如我们想查看当前某个用户是否登陆,那么新建脚本 finduser.sh

$1 就是指执行脚本传入的第一个参数 root

理想状态下,是这样的,但是如果用户不输入参数,脚本就会报错了,所以更好的情况是把脚本可能出现的事件都做个判断以及友情的提示,更加智能化

基本的正则表达式(BRE)

^tolstoy$: 正好包含这7个字母的一行,没有其他的任何字符. tol.toy:在一行的任意位居中,含有tol这三个字母,加上一个特殊字符,在接着toy这三个字母 tol.*toy:在一行的任意位居中,含有tol这三个字母,加上任意的0或者多个字符,
*: 代表0个或者多个任意字符
?: 代表一定有一个的任意字符
[]: 代表一定有一个在括号内的字符(非任意字符).例如[abcd]代表一定有一个字符,可能是abcd这四个选项的任意一个.
[-]: 代表在编码顺序内的所有自负.例如:0-9代表0到9之间的所有数字,因为数字的语系编码是连续的.
[^]: 若括号内的第一个字符为指数字符\(^) 表示反选,例如:\^abc代表是非abc的其他字符就可以.
shell中的特殊字符
\: 将特殊字符或者通配符还原成一般字符 |: 管道符,分割两个管线命令的界定 ;: 连续命令下达分隔符 $: 放在变量前面,正确使用变量 &: 工作控制,将命令编程背景下工作 !: 非(!)的意思,逻辑运算符 >'': 单引号,不具有变量置换的功能 >"": 双引号,具有变量置换的功能 >{]: 在中间为命令块的组合
shell中正则表达式的控制字符
*: 对*之前的匹配整体或字符匹配任意次(包括0次) \?: 对\?之前的匹配整体或字符匹配0次或1次 \{n\}: 对 \ { 之前的匹配整体或字符匹配n次 \{m,\}: 对 \ { 之前的匹配整体或字符匹配至少m次 [abcdef]: 对单字符而言匹配中的字符 [a-z]; 对单字符而言,匹配任意一个小写字母 [^a-z]: 不匹配括号中的内容

1.匹配一般字符:一般字符是指无特殊含义的字符,包括所有文本和数字字符,绝大多数的空白字符以及标点符号字符,因此,正则a,匹配a.

2.如果相匹配,因为是特殊字符,所以需要用 \ 转义,正则*,匹配*.

4.使用方括号表达式.例如x[abcdefg]z,可以匹配xaz,xbz,等,方括号里如果存在(^),表示取反的意思,就是说不匹配列表里的任意字符.

[]表示所数字,但是这样写太麻烦,我们可以用[0-9]来表示,[abcdefg]同样可以用[a-g]

最简单的办法就是把它们一一列出来:正则abc匹配于abc.
虽然(.)meta字符与方括号表达式都提供了依次匹配一个字符的很好方式,单正则真正强大而有力地功能是修饰符meta字符的使用上.
最常用的修饰符是(*),表示匹配0个或多个前面的单个字符.因此ab*c表示”匹配一个a,0个或多个b字符以及a空c”.这个正则匹配的有ac,abc,abbcabbbbc.
匹配0或多个,不表示匹配其他的某一个.例如正则abc,文本aQc是不匹配的.但是ac是匹配的.
(
)修饰符虽然好用,但是他没有限制,如要只要指定次数,使用一个复杂的方括号表达式虽然也能指定次数,但是太过麻烦.我们就引入了区间表达式.所谓的区间表达式有三种变化
\{n\} 前置正则表达式所得结果重现n次
\{n,\} 前置正则表达式所得结果至少出现n次

两个meta字符是脱节符号(^),与货币字符($),他们叫做锚点,因为其用途在限制正则表达式匹配时,针对要被匹配字符的开始或者结尾处进行匹配,

BRE运算优先级,由高到低

扩展正则表达式(ERE)

BRE与ERE在大多数的meta字符与功能应用上几乎是完全一致,单ERE理由写meta字符看起来与BRE类似,却具有完全不同的类型.

扩展正则表达式与基础正则表达式的唯一区别在于:? + () {} 这几个字符。
基础正则表达式中,如果你想? + () {}表示特殊含义,你需要将他们转义
而扩展正则表达式中,如果你想? + () {} 不表示特殊含义,你需要将他们转义。
转义符号,都是一样的,\符号。
所谓特殊含义,就是正则表达式中的含义。非特殊含义,就是这个符号本身。

\#egrep使用的是扩展正则表达式

如果希望打印文件,最好预先处理一下,包括调整边距,设置行高,设置标题等,这样打印出来的文件更加美观.当然,不处理也能打印,但是可能会比较丑陋.

pr命令就是转换文件格式的,可以把较大的文件分割成多个页面进行打印,并未每个页面添加标题.

> -d:两倍行距(并不是所有版本的pr都有效)

例如我有一个文件food,里面的内容为:

pr会以文件的修改时间作为页面标题的时间戳;如果输入时自管道而来,则使用当前的时间,接上文件名称(如果输入的数据内容在管道中,则为空)以及页码.

lp 和 lpr 命令将文件传送到打印机进行打印。使用 pr 命令将文件格式化后就可以使用这两个命令来打印。

命令成功执行会返回一个表示打印任务的ID,通过这个ID可以取消打印或者查看打印状态。

如果你希望打印多份文件,可以使用 lp 的 -nNum 选项,或者 lpr 命令的 -Num 选项。Num 是一个数字,可以随意设置。

如果系统连接了多台打印机,可以使用 lp 命令的 -dprinter 选项,或者 lpr 命令的 -Pprinter 选项来选择打印机。printer 为打印机名称。
lpstat 命令可以查看打印机的缓存队列(有多少个文件等待打印),包括任务ID、所有者、文件大小、请求时间和请求状态。

提示:等待打印的文件会被放到打印机的的缓存队列中。

使用 lpstat -o 命令查看打印机中所有等待打印的文件,lpstat -o 命令按照打印顺序输出队列中的文件。

cancel 和 lprm 分别用来终止 lp 和 lpr 的打印请求。使用这两个命令,需要指定ID(由 lp 或 lpq 返回)或打印机名称。
lprm 命令用来取消当前用户的正在等待打印的文件,使用任务号作为参数可以取消指定文件,使用横线(-)作为参数可以取消所有文件。
lprm 会返回被取消的文件名。

个人觉得最好用的显示文本文件的头几行最好用的是 head -n [file(s)]

在交互式shell通信期中,有时需要监控某个文件的输出----如日志这类持续写入状态的文件.-f选项这时就派上用场了,他可以要求tail显示指定的文件结尾行数,接着进入无止境的循环中----休息一秒后又再度醒来并检查是否需要显示更多的输出结果.再设置-f的状态下,tail只有当你中断它时才会停止----通常是输入Ctrl+C来中断;

直到按了ctrl+c选项后才停止.
由于tail加上-f选项之后便不会自己中断,所以此选项不能用于shell脚本.使用-f选项有实时监听的效果.

> 相似的,显示文件的前n个字节,以及除了最后n个字节以外的内容也没问题了. #所谓的参数的展开,基本上就是变量,shell中,参数是变量的超集,只不过变量不能以数字开头,而参数可以,比如$1,表示传递的第一个参数 ${10} #大于9的时候要用花括号 $* #接收所有参数, $@ #传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同 #但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体!以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。 $? #上个命令的退出状态,或函数的返回值
展开运算符(参数的运算符)
#如果varname存在且不是NULL,返回varname,反之,设为zili。可用于设置变量默认值!! 作用:与前例相似,唯一不同的是从$parameter的为不开始匹配. 分析:匹配案例中的”.”时,shell会从$var的尾部开始查找”.”,如果是最短匹配(echo ${var%.*}),则会找到第一个”.”就停止,否则(echo ${var%%.*})会一直找到最后一个”.”才停止.可以看到,这种用法可以分方便的去掉文件后缀,从而得到文件名.

退出状态和 if 语句

每一条命令,不管是内置的,shell函数,还是外部的,当它退出时,都会返回一个小的整数值给引用它的程序,这就是程序的退出状态.在shell下执行进程有很多方式可取用程序的退出状态.

以管理状态来说,0 表示成功,也就是当$? 返回的值为0的时候,证明程序执行成功,其他为失败

>0 #在重定向或单词展开期间(~,变量,命令,算数展开,以及单词切割)失败 1-125 #命令不成功的退出.特定的退出值的含义,是由各个单独的命令定义的. 126 #命令找到了,但文件无法执行 >128 #命令因受到信号而死亡 ##进入脚本所在目录 否则退出

if 与[ 之间必须有空格

[ ]与判断条件之间也必须有空格

]与; 之间不能有空格

str1 = str2    当两个串有相同内容、长度时为真
-n str1      当串的长度大于0时为真(串非空)
-z str1      当串的长度为0时为真(空串)
-r file     用户可读为真
-w file     用户可写为真
-x file     用户可执行为真
-b file 若文件存在且是一个块特殊文件,则为真
-c file 若文件存在且是一个字符特殊文件,则为真
-d file 若文件存在且是一个目录,则为真
-e file 若文件存在,则为真
-f file 若文件存在且是一个规则文件,则为真
-g file 若文件存在且设置了SGID位的值,则为真
-h file 若文件存在且为一个符合链接,则为真
-p file 若文件存在且为一已命名管道,则为真
-s file 若文件存在且其大小大于零,则为真
-u file 若文件存在且设置了SUID位,则为真
-o file 若文件存在且被有效用户ID所拥有,则为真
-a        与
注意:在[] 表达式中,常见的>,<需要加转义字符,表示字符串大小比较,以acill码位置作为比较。不直接支持<>运算符,还有逻辑运算符 || 和 && 它需要用-a[and] –o[or]表示。 注意:[[]] 运算符只是[]运算符的扩充。能够支持<,>符号运算不需要转义符,它还是以字符串比较大小。里面支持逻辑运算符 || 和 && bash 的条件表达式中有三个几乎等效的符号和命令:test,[]和[[]]。通常,大家习惯用if [];then这样的形式。而[[]]的出现,根据ABS所说,是为了兼容><之类的运算符。 不考虑对低版本bash和对sh的兼容的情况下,用[[]]是兼容性强,而且性能比较快,在做条件运算时候,可以使用该运算符。

) 相当于其他语言中的default。
除了
)模式,各个分支中;;是必须的,;;相当于其他语言中的break
| 分割多个模式,相当于or

for循环是将串行的元素取出,依次放入指定的变量中,重复执行在do和done之间的命令,直到所有元素取尽为止

#条件为真时,循环停止

shift每执行一次,参数指针像右移动一位,

第一个参数为: 1 参数个数为: 4 第一个参数为: 2 参数个数为: 3 第一个参数为: 3 参数个数为: 2 第一个参数为: 4 参数个数为: 1

Linux相关命令详解

-A 1 表示找到所有匹配行,并显示所有匹配行后的一行
-B 1 表示找到所有匹配行,并显示所有匹配行的前面一行
-C 1表示找到所有匹配行,并显示所有匹配行的前一行,后一行
-a 表示把所有文件当作ASCII文件来处理 搜索二进制文件
-e 后面跟一个正则表达式,指定多个正则表达式的时候很有用
-f可以指定pattern在我们的文件中 pattern文件中的每一行都会来进行匹配
-i:模式匹配时忽略大小写
-l 出匹配模式的文件名称,而不是打印匹配的行
-m 最多匹配几个后,就停止,这样速度会比较快
-n 匹配之后,在前面打印行号,这个还是有用的
-o 只打印匹配的内容

-c或——complerment:取代所有不属于第一字符集的字符;
-d或——delete:删除所有属于第一字符集的字符;
-s或——squeeze-repeats:把连续重复的字符以单独一个字符表示;
-t或——truncate-set1:先删除第一字符集较第二字符集多出的字符。

字符集1:指定要转换或删除的原字符集。当执行转换操作时,必须使用参数“字符集2”指定转换的目标字符集。但执行删除操作时,不需要参数“字符集2”;
字符集2:指定要转换成的目标字符集。

输入的字符串大写转成小写:

#由于是转换,所以必须要有字符集2 也就是'a-z'

用tr压缩字符,可以压缩输入中重复的字符:

-n :只打印模式匹配的行
-e :直接在命令行模式上进行sed动作编辑,此为默认选项
-r :支持扩展表达式
-i :直接修改文件内容

^ 锚点行首的符合条件的内容,用法格式"^pattern"
$ 锚点行首的符合条件的内容,用法格式"pattern$"
* 匹配紧挨在前面的字符任意次(0,1,多次)
.* 匹配任意长度的任意字符
? 匹配紧挨在前面的字符0次或1次
\{m,n\} 匹配其前面的字符至少m次,至多n次
\{m,\} 匹配其前面的字符至少m次
[] 匹配指定范围内的任意单个字符
[^] 匹配指定范围外的任意单个字符
p 打印匹配行(和-n选项一起合用)
a\ 在定位行号后附加新文本信息
i\ 在定位行号前插入新文本信息
c\ 用新文本替换定位文本
r filename 从另一个文件中读文本,类似输入重定向 <
s 使用替换模式替换相应模式
q 第一个模式匹配完成后退出或立即退出
l 显示与八进制ACSII代码等价的控制符
{} 在定位行执行的命令组,用分号隔开
n 从另一个文件中读文本下一行,并从下一条命令而不是第一条命令开始对其的处理
N 在数据流中添加下一行以创建用于处理的多行组
y 传送字符,替换单个字符
sed替换(脚本中较多使用)
#匹配IPADDR的行,把22.1替换成10.12由于.号有特殊意义所有需要转义 #把所有匹配到bin的行中第二次及第二次之后出现bin替换成tom #把所有匹配到bin的行中第二次出现的daemon替换成jerry,并在生产与匹配行同样的行 #把所有匹配到adm的行中仅仅只是第二次出现的adm替换成boss #把root用括号括起来,&表示引用前面匹配的字符 #匹配ONBOOT的行的前面添加#号,在配置文件中也表示注释某行 #匹配ONBOOT的行,把#替换成空,即去掉#号,也一般用作去掉#注释
sed 引用变量 (脚本中也较多使用)

第一种当sed命令里面没有默认的变量时可以把单引号改成双引号
第二种当sed命令里面有默认的变量时,自己定义的变量需加单引号,且sed里面的语句必须用单引

操作一个文件,并写入到另一个文件

#把sed操作的文件内容保存到另外一个文件中,w表示保存,ip.txt文件名

读取一个文件到正在用sed操作的文件中

#在匹配Ethernet的行,读进来另一个文件的内容,读进来的文件的内容会插入到匹配Ethernet的行后 #在匹配Ethernet的行,读进来另一个文件的内容,读进来的文件的内容会插入到匹配Ethernet的行后 #逐行读取并打印出来,默认以空格分割 #读取每行的第一个域的内容,并打印出来 #匹配的列,只要有匹配就打印,不分域 #count是自定义变量,这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0. #统计某个文件夹下的文件占用的字节数
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
ORS 输出记录分隔符
#统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

awk可以做很多事情,赋值,运算,变量等等...具体就不一一说明了,自行搜索.

-b:忽略每行前面开始处的空格字符;
-c:检查文件是否已经按照顺序排序,排序过为真;
-d:排序时,处理英文字母、数字和空格字符,以字典顺序排序。忽略其他所有字符;
-f:排序时,将小写字母视为大写字母;
-i:排序时,处理040~176之间的ASCII字符,忽略其他所有字符;
-m:将几个排序好的文件进行合并;
-M:将前面3个字母按月份的缩写进行排序;
-n:按照数值大小进行排序;
-r:以相反的顺序进行排序;
-k:指定需要排序的列数(栏数);就是指定按第几列进行排序
-t 分隔符:指定排序时所用到的栏位分隔符;
-u 去重 不过一般使用 uniq操作
### 以下划线为分割 第一第二列进行排序,那么默认第三列会按顺序进行排序,所以结果会被打乱
#所以,sort提供了--stable参数来进行补救。
 -c, --count //在每行前加上表示相应行目出现次数的前缀编号
 --help //显示此帮助信息并退出

1,对文本操作时,它一般会和sort命令进行组合使用,因为uniq 不会检查重复的行,除非它们是相邻的行。如果您想先对输入排序,使用sort -u。
2,对文本操作时,若域中为先空字符(通常包括空格以及制表符),然后非空字符,域中字符前的空字符将被跳过

-s 截断长行,但不合并
-t 除每个段落的第1行外都缩进
-u 改变格式化,使字之间出现一个空格,句子之间出现两个空格
-w n 将输出的行宽改为n个字符。不带该选项时,fmt输出的行宽度为75个字符
例如,我有一个文件demo,内容为:
 
 
该命令的含义是节段2长行.
 
使用fmt -t demo命令的意思是说排除首行的缩进,结果为:
 
 
使用fmt -u demo命令的意思是说格式化单词和句子的间隔.输出为:
显然A little boy前面的多个空格变成了两个.
 
使用命令fmt -w 40 demo意思是说指定行的宽度,这里的行宽为40个字符.所以输出为:
 
仅作切割的选项: -s , 在你想将长的行绕回,短的行保持不动时很好用,这么做也能使结果与原始版本间的差异达到最小,例如:
 
-m:统计字符数.这个标志不能与-c标志一起使用 -w:统计字数.一个字被定义为由空白,挑个或换行字符分隔的字符串. -L:打印最常行的长度
-s 指定分隔符,默认是换行
-w 等位补全,就是宽度相等,不足的前面补 0
-f 格式化输出,就是指定打印的格式
# %后面指定数字的位数 默认是%g,%3g那么数字位数不足部分是空格。
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...

  • 本文承接之前写的三十分钟学会AWK一文,在学习完AWK之后,趁热打铁又学习了一下SED,不得不说这两个工具真的堪称...

  • 血色秋阳余辉艳, 红霞映亮水中天。 归巢白鹭寻好域, 喜看...

  • 我一直在强调我大学毕业就是一个小白,没有人家那么多在大学期间打工的经验,我只是在单纯的过自己的学生时代,勾心斗角的...

  • 小时候,我们总会想象着长大后的自己过着怎样的生活,遇见怎样的人,展开怎样的故事。有人说,随着时间的洗礼,我...

我要回帖

更多关于 else if的用法 的文章

 

随机推荐