shell笔记

Type cmd可以查看命令是系统自带还是安装程序,如果不是内嵌命令,一般会提醒安装的地址,如果没有,会提醒如何安装所以shell才成为命令解释器
Shell:
  • shell接受用户输入的命令,并把它送入内核去执行,内核是linux系统的心脏,从开机自检时就就驻留在计算机的内存中,直到计算机关闭为止;shell是一种应用程序,应用程序只有当被调用时才被调入内存中,它是用户使用unix/linux的桥梁,用户的大部分工作都是通过shell完成的;
  • shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式的解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数。Shell虽然不是unix/linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。
shell与编译型语言的差异:
很多传统型语言例如C、C++等都是编译型语言,这类语言需要预先将我们写好的源代码转换为目标代码,这个过程叫做编译;运行程序时,直接读取目标代码;由于编译后的目标代码非常接近计算机底层,因此执行效率很高,这是编译语言的优点。
解释型语言也被称为脚本语言,是为了缩短编译型语言编写-编译-链接-运行过程而创建的计算机编程语言。执行这类程序时,解释器需要读取我们编写的源代码,并将其转换为目标代码,再由计算机运行。由于每次都要编译。所以效率有所下降。使用的好处是:脚本语言多半运行在比编译语言更高级的层级,能够轻易的处理文件与目录之类的对象;缺点是:效率通常不如编译语言,脚本语言有:awk、perl、python、shell

Shell有两种执行命令的方式:
1)交互式:解释执行用户的命令,用户输入一条命令,shell就解释一条
2)批处理:用户事先写一个shell脚本,其中有很多命令,让shell一次把命令执行完,而不必一条一条的执行。

常见的shell:
shell是一种脚本语言,就必须有解释器来执行这些脚本
linux/unix上常见的脚本解释器有bash\sh\csh\ksh等,习惯上把它们称为一种shell,其实就是shell脚本解释器,解释器本身是编译型程序。
bash(BourneAgain Shell):bash是linux标准默认的shell,内部命令有40个,基于sh,完全兼容sh
sh(Bourne Shell):是unix标准默认的shell
ash:是linux中占用资源最少的一个小shell,只包含24个内部命令,使用不方便
csh:csh是linux比较大的内核,有52个内部命令
ksh(Korn shell):共有42条内部命令
什么时候使用shell:
因为shell是各unix系统之间通用的功能,并且经过了posix的标准化,shell脚本只要写一次很好的,就可以应用到很多系统中:
1)简单性:shell是一个高级语言,可以简洁的表达复杂的操作
2)可移植性:使用posix所定义的功能,可以做到脚本不用修改就可以在不同的系统上执行
3)开发容易:短时间就可以完成一个功能强大又好用的脚本
不过一般处理使用资源密集型和复杂大型的应用不要使用shell
第一个shell脚本:
shell脚本的扩展名是.sh,表示shell;
!#(sha bang符号)是一个约定的标记,告诉系统这个脚本需要什么解释器来执行(解释器的路径)
作为可执行程序:
将代码保存为XXX.sh,并在相应目录下执行脚本:./XXX.sh。运行其他二进制的程序也一样,直接写XXX.sh,linux系统会去PATH里村着有没有叫XXX.sh的,但是PATH没有包含所有路径,所以没有加上./是会找不到命令的;要用./告诉系统,就在当前目录找(这里的系统指的是就是shell这个应用程序)
作为解释器参数:
这种运行方式就是直接运行解释器,文件名作为其参数,如:/bin/sh XXX.sh;这种运行方式,不需要在第一行指定解释器信息,写了也没用;

命令(command):命令是shell脚本的最基本元素,一般是由命令名称、选项和参数三部分组成;选项是开头一个-号加上一个或者多个字母,是对命令的补充说明;分号(;)用来分隔同一行的多个命令。
man命令:man【命令名称】可以查看命令的手册页。
read命令:指从端口输入数据:read PERSON:指输入数据作为变量PERSON的值。
chmod命令:可以为脚本赋予执行权限
cp命令:移动文件,移动目录时应该加上-r
mv命令:可以用来移动文件,也可以用来重命名;mv 选项 源文件 目标文件;其中如果目标文件类型是文件时,mv命令就会将所给的源文件或目录重命名为给定的目标文件名;如果目标文件是已存在的目录名,mv命令会先把源文件移动到对应的目录,再把原有文件删除,从而导致该文件的链接丢失。
find命令:find 路径 -匹配项;比如:find . -name 't*' -print表示匹配有t的文件并将将文件输出到标准输出
mkdir命令:创建目录
touch命令:创建新文件
vi编辑器同gedit编辑器不一样:vi适用于命令行界面,而gedit适用于图形界面

正则表达式:
正则表达式是由一串字符和元字符构成的字符串,简称RE;主要功能是文本查询和字符串操作。
元字符是用来解释字符表达式意义的字符,它用于对字符表达式的内容、转换和各种操作信息进行描述。包括*、^、[]等。而abc123属于普通字符。
POSIX标准中将正则表达式分为基本的正则表达式还有扩展的正则表达式。

基本的正则表达式中有:
*:
匹配前面一个普通字符的0次或者多次,如hel*o:可以表示hello、helllo等
.:
匹配任意一个字符,一个点匹配一个字符
^:
匹配行首,表示匹配行首是^后面字符的行
$:
匹配行尾
^$:
表示匹配空行
^.$:
表示匹配只有一个字符的行
[]:
该符号支持穷举列出字符集合的所有元素,也支持使用-表示字符集合范围;当^在[]中时不是表示行首,表示取反,即匹配不是在这个范围内的
[]*:
可以匹配任意一个英文单词,表示任意一个字符开头,再以任意一个字符惊醒0次或者任意次重复。
\:
转义符,用于屏蔽一个元字符的特殊意义
\<\>:
精确匹配符号,该符号利用\屏蔽了<>的特殊意义,如:\表示精确匹配the这个单词
\{\}:
意义同*很像,*表示匹配前一个字符0或者任意个,而这个可以指定个数,\{n\}匹配前面一个字符出现n次; \{n,\}匹配前面一个字符至少出现n次; \{n,m\}匹配前面一个字符出现n到m次;举例:精确匹配5个小写字母:[a-z]\{5\}

扩展元字符:

?:
匹配0和或者1个在其之前的那个普通字符
+:
匹配1个或者多个在其之前的那个普通字符,与*不同在于*可以匹配0个,+和*都是放在要普通字符的后面
():
表示一个字符集合或用在expr中
|:
表示或,匹配一组可选的字符;()和|结合使用,表示一组可选字符的组合,如re(a|e|o)d,但其实用[]就可以代替了,如re[aeo]d
bash shell本身并不支持表达式,使用正则表达式的是shell命令和工具;不过bash可以使用正则表达式中的一些元字符实现通配功能
通配:通配就是把一个包含通配符的非具体文件名扩展存储在计算机、服务器或者网络上的一批具体文件名的过程,元字符在通配的意义与正则表达式的意义不完全相同。
如:*表示任意位数的任意字符,?表示任意一个字符,^不表示行首,表示取反;[]:[a-h]*.awk表示匹配以
文件名是小写字母同时后缀是awk的文件;{}:{,}用逗号隔开,表示或,匹配其中任意一个的文件

grep命令是针对文件内容的,如果针对文件,应该利用管道 ll |grep 75
grep命令:
grep是Global search Regular Expression and Print out the line的缩写,是一种强大的文本搜索工具,能使用正则表达式搜索文本,并把匹配的行打印出来。
一般格式是 grep 选项 模式 文件
模式非常灵活,可以是字符串、变量或者正则表达式,只要模式中有空格就需要加上双引号;
选项有:
-c
 表示匹配字符串的数量,默认情况下会打印出包含模式的所有行;一旦加上-c选项就只会显示包含模式行的数量。
-n
列出所有的匹配行并显示行号;默认情况下搜索多个文件时显示文件名及每行的内容,加上-n选项后将在每行内容前附加显示行号
-v
显示不包含模式的所有行,使用-vc结合可以列出文件不包含模式的行数
-i
表示grep命令不区分大小写,默认情况下是区分大小写的
h
表示多个文件查询时不显示文件名
-l
表示只列出符合匹配的文件名而不列出匹配行
-s
表示不显示不存在或无匹配文本的错误信息
-r
表示递归搜索,默认情况下只对当前目录下的文件进行搜索,不是对子目录中的文件进行搜索
-w
表示元字符不再解释为特殊意含义,也可以表示精确匹配
-x
表示匹配整行,就是只有当文件中有整行内容和模式相符时才输出该行
-q
表示不输出结果,而是以推出状态表示搜索是否成功,0表示搜索成功,1表示未搜索到符合的结果,2表示命令或者程序由于错误未能执行
echo $?
输出上一条命令的退出状态
-b
打印出匹配行距文件头部的偏移量,-o打印出匹配词距文件头部的词偏移量
暂时发现在终端和在.sh中都是通配而不是元字符
grep和正则表达式结合使用:
1)匹配行首:grep ^- *.pem
2)  匹配空行:grep -c ^$ *.pem,列出空行的个数
3)设置大小写:可以利用grep 命令不区分大小写,也可以用[],如grep -n [Cc]at *.pem,表示匹配Cat和cat
4)匹配重复字符:匹配字符可以利用“.”和“*”来实现
5)转义字符:\,每一个元字符都要加上转义字符,包括-也要,因为-在grep表示选项的意思;
使用grep加上转义符时尽量加上``

sed命令基本用法:
sed是一个非交互式文本编辑器,它可对文本文件和标准输入进行编辑,标准输入可以来自键盘、文件重定向、字符串等;sed只是对缓冲区中的原始文件的副本进行编辑,并不编辑原始文件,如果需要改动文件,需要将输出重定向到另一个文件。sed会从文本行或者标准输入中都去数据,将其复制到缓冲区,然后读取命令行或者脚本的第一个命令,对此命令进行编辑,重复此过程,直到命令行或者脚本中所有的命令都执行完毕;所以sed相对与vi编辑器的优点在于可以一次性处理所有的编辑任务,比较高效
sed命令选项(-n -e -f)
如: sed -n '30p' test-2.txt
-n
是选项,跟grep的选项是同个概念,在这里表示只输出匹配的,不用输出剩下的内容;而‘30p’则表示输出第三十行的内容,p是sed编辑命令,表示打印匹配行。Test-2.txt则表示输入的文本。p命令还可以制定‘30,40p’表示输出30行到40行之间的内容;‘/word/’表示匹配word输出匹配的行;
-e
表示将下一个字符解析为sed编辑命令,如:sed -n -e '/shot/p' -e '/house/=' test-2.txt,执行的过程是对输入文件每一行进行扫描,匹配的就输出;在这里,-e表示将下一个字符解析为sed命令;因为它不支持同时带多个编辑名令的用法,所以有多个命令时要使用-e;
-f
只有在调用sed脚本文件才起作用,追加本文、插入文本、修改文本和删除文本和替换文本等功能往往需要几条sed命令完成。
a\是sed的文本添加编辑命令,/word/a\表示在word后面添加文本,如果没有指定位置,sed会默认在每一行后面添加;如:
#! /bin/sed -f
/catttt/a\
dog love cat\
cat love dog too\
cccccccccccc
sed在完成追加脚本只会把结果输出到shell来,原始文件不会受到改变;sed选项使用-f表示正在调用脚本文件
sed的文本定位:
匹配元字符:如果sed所要匹配的目标字符中包含元字符,需要\屏蔽其特殊意义,如sed -n '/\./p' test-2.txt
使用元字符进行匹配:sed可以灵活使用正则表达式的元字符进行匹配;$在正则表达式表示行尾,在sed命令表示最后一行;sed基本编辑命令可以放在单引号内,也可放在单引号外如 sed -n '$'p test.txt
或sed -n '/.*bus/ p' test.txt表示匹配包含以bus结尾的字符串的行(用.和*匹配进行任意字符的匹配)
!符号:!表示取反,x,y!表示不在x到y行号范围内的行,但是!不能用于关键字不匹配,无法表示与关键字不匹配的行。
使用行号和关键字限定行范围:可以/word/,x这样来限定行范围
sed的编辑命令:(可以命令实现也可以脚本)
插入文本:i\,i\与a\的区别仅在与a是在匹配行的后面追加内容,而i是在匹配行的前面插入文本。
修改文本:c\,表示将匹配的行整行换掉,
删除文本:d,如sed '/1d/p' test.txt,用数字表示行号,用$表示最后一行
替换文本:s,与修改文本的差别在于s可以替换一个字符串,替换选项对sedsed替换操作做进一步的细化,g表示替换文本中所有出现被替换字符串之处;p与-n结合只打印替代行,w表示将输出定向到一个文件
p和-n表示输出被替换的部分,p和-n分开使用,只用-n时没有输出结果。如:sed -n 's/--/cc/p' test-2.txt,p可以指定替换每一行的第几个数据,如 sed -n 's/--/cc/3p' test-2.txt
g跟p的区别:在于输出所有被替换的部分,p是在遇到每一行的第一个被替换字符串时,替换后就跳到下一行了。
&:可以用&来保存被替换的字符,如 sed -n 's/--/(&)/p' test-2.txt,其中&表示--,--被替换为(--);
w:在后面加上文件名,定向输出到指定文件中;如果文件不存在,就创建相应的文件。
从文件中读入文本:r,r通知sed从别的文件源读取文件,如 sed '/catcat/r test.txt' test-2.txt;
退出命令:q,表示完成指定位置的匹配后立即退出,如:sed '5 q'test.txt,表示打印前五行后退出;如 sed -n '/cat/p' test-2.txt会打印出匹配的所有行,而q会打印直到找到第一个的前面的内容。
变换命令:y把一系列的字符换成相应的字符,sed y表示对字符的逐个处理,要求是被替换的字符序列和变换的字符序列等长。如sed 'y/catt/CATT/' test-2.txt
显示控制字符:l,表示显示出文本中的控制字符
在定位行执行命令组:作用与-e类似,如sed '/cat/{p,=}'test.txt
补充:sed中的三种调用方式:
1)命令行执行,如:sed 's/\\OU/ou/' test.txt
2)脚本执行:在文本中写:s/\\OU/ou/;终端输入sed -f 脚本文件 输入文件
3)可执行文件执行:在文本中写:sed ’s/\\OU/ou/‘ test.txt

备注:-f的意思是调用脚本语言,所以在文本中是不需要加入-f的;可执行文件的输入文件也可以在终端输入
sed用;和-e和{}分隔多个编辑命令
sed -n '3,8!p' test.txt
sed  -e '/\\OU/a\We find \\OU' -e 's/\\OU/(ou)/'  test.txt
sed -n '/o*/p' test.txt
sed -n '/o\{2,\}/p' test.txt
sed -n '/o\{1,\}/p' test.txt
sed -e  'y/abcde/EDCBA/' -e 'w output' test-1.txt 试过很多次,好像只能分开,不过这个最后写入文件的修改后的
sed -i 'y/abcde/EDCBA/' test-1替换命令,同时替代原文件,一般都会用w写回原文件,后来发现w只是可以写入新文件,用-i选项可以实现

awk编程:awksed相似,都是用来处理进行文本处理的,awk语言可以从文件或字符串中基于指定规则浏览和抽取信息,在抽取信息的基础上才可以进行其他文本操作
grep、sed和awk都是有三种执行方式:1)命令行执行2)直接用对应的命令调用脚本3)将命令插入脚本,设置脚本为可执行
awk语句都由模式和动作组成。模式是一组用于测试输入行是否需要执行动作的规则,而动作是包含语句、函数和表达式的执行过程。awk支持?和+两个扩展元字符,而grep和sed不支持;如: awk '/cat/{print "hi"}' test.txt,指的是打印有cat的行;
awk编程是由一个主输入循环维持,主输入循环反复执行,知道终止条件被触发;主循环无须写,awk已经写好了,我们写的代码会被嵌入其中;awk还定义了两个特殊字符:BEGIN和END;
记录和域:awk将每个输入行定义为记录,行中的每个字符串定义为域,域之间用空格、tab或其他符号进行分隔,称为分隔符,awk定义了$来制定执行动作的域,域操作符$后面跟数字或变量来标识域的位置。如awk '{print $0}' test-1;
awk的默认配置:分隔符是空格,我们可以通过-F或FS来标示分隔符,如awk 'BEGIN{FS=":"} {print $3}' test
关系和布尔运算符:~表示匹配正则表达式,!~表示不匹配;awk在进行模式匹配时,常使用条件语句,if-else;布尔运算符:|| && !如:awk 'BEGIN{FS=":"} {if($4==00)print $0}' test-1
awk 'BEGIN{FS=":";OFS=":"} {total=$4+$5+$6+$7;if(total<200) print $1,$2 }' test-1
表达式:awk定义变量非常方便,只要(字母、数字和下划线)赋值即可,变量不能数字开头,且区分大小写;变量的默认值是0,字符串默认值是空。
#! /usr/bin/awk -f 

BEGIN{FS=":"} 
{total=$4+$5+$6+$7 
print $1,total}
./20150804-1.awk test-1
系统变量:
awk定义了内建变量用于设置环境信息,称为系统变量,一种是改变awk的默认值,还有一种是读取某些系统值;如awk 'BEGIN{FS=":"} {print NF,NR,$0} END{print FILENAME}' test-1表示输出行号和每行的域数,在结束时输出文件名
格式化输出:
引用c中对数值的处理,如:awk 'BEGIN{FS=":"} {printf("%d\t%d",$4,$5)}' test-1,记得是printf而不是print;其中-15表示控制字符长度,为左对齐,另外浮点数控制如%10.3f表示字符长度为10,小数点后3位,为右对齐;
内置字符串函数:
awk提供了强大的内置字符串函数,用于实现字符串的字符串替换、查找和分隔等功能;如awk 'BEGIN{FS=":";OFS=","} gsub(/cai/,"Cai",$1)' test-1其中OFS表示输出分隔符,gusb是函数,表示在$1中将cai替换成Cai;如果没有指定$1,则表示在输入中改;如:awk 'BEGIN {print length("cai")}'其中length表示输出长度,而且经验证,必须加上BEGIN
向awk脚本传递参数
awk -f 20150804-1.awk max=3 FS=":" test-1或这./20150804-1.awk max=3 FS=":" test-1都可以
条件和循环语句
同c一样
数组:
awk数组的形式同c一样,但是不用定义数组的类型和大小,可以直接赋值后使用;关联数组:是指数组的索引可以是数字也可以是字符串;数组的split函数:表示split(r,s,t)将字符串以t作为分隔符,将r字符串拆分为字符串数组,并且存放在s中;
数组形式的系统变量:
ARGC和ENVIRON,ARGC是ARGV数组中元素的个数;如#! /usr/bin/awk -f ,如:BEGIN{ for(x=0;x
          print ARGV[x]; 
	  print ARGC; } 在命令行执行./20150804-1.awk abc sdf dfg;结果ARGC是4;因为在这里没有输入文件,所以ARGV[0]=awk,就是该脚本的程序名;接下来三个就是输入的三个程序名;如果有输入文件,如
./20150804-1.awk abc sdf dfg test-1这里的ARGC就会是5,ARGV[4]为输入文件名;
备注:关于匹配大小写:sed:sed -n  's/[Gg][Gg][Gg]/HEY/p' test.txt,其中是把匹配单词每个字母都进行匹配大小写;awk:awk 'BEGIN{IGNORECASE=true}/ggg/{print("HEY")}' test.txt,系统变量IGNORECASE为真时表示忽略大小写的匹配。目前尚未解决awk匹配的问题

补充:awk -v命令同BEGIN类似,定义变量,不能连级定义;
         RS和ORS表示的是记录分隔符,默认是换行符;FS和OFS表示的是字段分隔符,默认是空格符;
文件的合并、排序和分割:
sort命令:sort命令就是一种对文件排序的工具
sort命令将输入文件看做多条记录组成的数据库,换行符作为定界符;sort命令也可将记录分为多个域,默认空格符作为域分隔符。格式为 sort 选项 输入文件
-t:
sort test排序是默认是以空格符为域分界符,会以第一域的字符串的首字母进行排序,相同就比较第二个字母,以此类推;-t是改变域分界符的,如sort -t: test,-t和:是没有空格的
-k:
k是指定某一域排序,如sort -k2 test,k2表示对第二域排序,而且数字也会被当成字符串进行排序,也就是是一个数字一个数字排序
-n:
指定按照数字大小进行排序,如:sort -n -k2 test-1或sort -k2n  test-1
-r:
表示逆序排序
-u:
去除排序结果中的重复行
-o:
将排序结果输入到另一个文件,使用-o加上文件名如: sort  -k2nr test-1 -o test-2
-c:
用于检测文件是否排好序,如: sort  -k2nr -c test-2,已经排序的不输出任何东西
-m:
用于将两个排好序的文件合并成一个排好序的文件
Sort和awk的联合使用:
如: cat test-2 |awk -v RS="" '{gsub("\n","@");print}'|sort|awk -v ORS="\n\n" '{gsub("@","\n");print}',将文件作为awk的输入数据,利用记录分隔符将输入文件按块划分,再对每一块中的换行符换为@;这样就是每一块变成每一行;利用sort排序,再用awk相反的输出。
uniq命令:用于去除文本的重复行,跟sort的-u类似,不同在于uniq只去除连续的重复,sort -u去除了所有重复的
-c:
显示每行在文本中重复出现的次数,如:uniq -c test-1
-d:
显示有重复的记录
-u:
显示无重复的记录(所有命令都是针对连续的重复
sed -e 's/\,/ /g' -e 's/\./ /g' -e 's/\:/ /g' -e 's/ /\n/g' "$1"|sort|uniq -c|sort -nr;将文本中的符号过滤掉,进行单词的出现次数排序
join命令:用于实现两个文件中记录的连接操作,就是关系数据库中的连接
join命令是将两个文件中具有相同的域的记录选择出来,将这些记录的所有域放在一行,成为一条记录。如:join test-2 test-1,其中文件的先后对域的排序有关系;join命令只能对已经排好序的文件进行操作(按照链接域排序)
-t:
改变域分隔符
-a和-v:
显示未进行连接的记录,就是除了找到相同的域的其他域,-a和-v的区别在于-a还会输出匹配的域,-v不会
-o:
join命令默认现实连接记录在两个文件中的所有域,而且按照顺序;-o选项改变结果显示 如:join -o1.2 2.1 1.3 test-1 test-2,1.1表示现实第一个文件的第一个域
-i:
比较域内容时忽略大小写
-1和-2:
指定连接的域,join命令默认比较文件1和文件2的第一域,-1 3表示用第一个文件的第三个域
cut命令:从标准输入文件或文本文件中按域或行提取文本
-c:指定提取的字符数或字符范围,如:cut -c3-7 test-1,取第三到第七个字符
-f:指定提取的域数或域范围:cut -f1 test-1
-d:改变域分隔符
paste命令:将文本文件或标准输出中的内容粘贴到新的文件,也可以将来自不同的文件的数据粘贴到一起,形成新的文件
-d:改变分隔符,是将新文件粘贴在后面,中间加上分隔符,因为paste是默认按列粘贴的
-s:将每个文件粘贴成一行,将默认改为按行粘贴
-:从标准输入中读取数据,如ls |paste - -:表示从输入中每行显示两个文件名
split命令:将大文件切割成小文件
-或-l:指定切割成小文件的行数:split -5 test-1 txt,表示切割test-1按5行切为一个名为txt的文件,如果有多个文件,就txtaa~txtzz;如果没有指定文件名字,就默认用x
-b:指定切割成小文件的字节
-C:与-b类似,但是尽量维持每行的完整性
tr命令:实现字符转换功能,其功能用sed都能实现
tar命令:tar是归档命令,也就是系统文件的压缩和解压缩
-c:创建新的包
-r:为包添加新的文件
-t:列出包的内容
-u:更新包中的文件,若包中无此文件,则将文件添加到包中
-x:解压缩文件
-f:使用压缩文件或设备时
-v:详细报告处理文件的信息
-z:用gizp压缩和解压文件
Shell变量:
定义变量:定义变量如:variabableName=“value”(变量名和等号之间不能有空格),变量名应遵循的规则:
1)变量名只能包括大小写字母、数字和下划线,不能以数字开头
2)中间有空格要用双引号括起来
3)不能使用bash的关键字(可以使用help查看保留关键字)
变量类型:运行shell会同时存在三种变量:
1)局部变量(本地变量):局部变量在脚本或命令中定义,仅在当前shell有效,其他shell启动的程序不能访问
2)环境变量:所有的程序,包括shell启动的程序,都能访问环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量
3)位置参数:属于变量,用于想shell脚本传递参数,是只读的
使用变量:
$:
使用一个定义过的变量,只需要在变量名前面加上$:echo $your_name;有时会在变量加上{},因为有可能有echo “I am good at ${shill}Script”为了方便解释器识别变量的边界,推荐尽量给每一个变量都加上{};
readonly:
只读变量命令可以将变量定义为只读变量,值不能改变;readonly XXX
unset:
删除变量:使用命令可以清除变量的值,不能删除只读变量(删除后访问没有任何输出)
variable=value:
将value值赋给变量
variable+value:
对已经赋值的变量,重设其值
variable?value
或variable:?value对未赋值的变量,显示系统错误信息,就是错误时会输出冒号后的值
variable:=value:
将未赋值的变量,将value赋值给它;如${colour:=blue},必须要用{}括起来
variable:-value:
同上一个,但是value不会储存到变量对应的地址空间;也就是一次性的意思
shell脚本变量是无类型的,并且同时有数值型和字符型两种赋值,如果判断变量中只有数字,shell会默认变量为数值型;数值型的初值是0,字符型的初值是空字符串,将字符型加1,输出值是1;
环境变量:
export:将变量定义为环境变量
env:显示所有的环境变量
unset:清除环境变量
重要的环境变量:
PWD和OLDPWD:PWD记录当前的目录路径,当利用cd命令修改路径时系统会自动更新PWD的值;OLDPWD记录前一个目录
PATH:用于帮助用户找到输入的命令,用户所输入的命令实际上是一个源代码文件,成为可执行文件
HOME:记录了当前用户的根目录
SHELL:保存默认的shell值
USER:表示已登录的用户的名字
UID:表示登录用户的ID
PPID:当前进程的父进程号
PS1和PS2:提示符变量
source:使环境变量文件立即生效
利用source执行执行脚本和在bash环境下执行有差别,只要是bash执行文件是启动一个子shell来执行命令,这样环境只有在子shell中生效;如果是用source,就会在bash以及子任务中生效
位置参数:
用于从命令行想shell脚本传递参数,$1表示第一个参数$2表示第二个参数
Shell的特殊变量:
变量名只能包含数字、字母和下划线,某些变量包含其他字符有特殊含义,这样的变量被称为特殊变量
如:$$:表示当前进程的ID,即pid
特殊变量-含义
$0:当前脚本的文件名
$n:传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$#:传递给脚本或函数的参数个数。
$*:传递给脚本或函数的所有参数。
$@:传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。
$?:上个命令的退出状态,或函数的返回值。
$$:当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
命令行参数:运行脚本时传递给脚本的参数称为命令行参数,用$n表示,
$*和$@的区别:
相同:都表示传递给函数或脚本的所有参数,不被双引号(“”)包含时,都以“$1””$2”....”$3”形式输出
不同:当“$*”时会以“$1$2$3...$n”的形式输出,而“$@仍一样”
退出状态:$?可以获得上一个命令的退出状态
引用:引用是指将字符串用引用符号引起来,以防止特殊字符被shell脚本重解释为其他意义
”“:引用除$、`、\、之外的所有字符,称为部分引用;有解析空格的作用
‘’:引用了所有字符,就是三个特殊符号也会被输出
``:shell将反引号中的内容解释为系统命令,先执行``内,结果作为外层的输入数据
$():与反引号在命令替换上是等价的,不过这个可以嵌套。如$(expr length “$(sed -n 1p input)”)
备注:``和$()属于命令替换;还有一个区别是``会将\处理为空格;$()不会;如echo `echo \\`输出空;echo $(echo \\)输出\
转义:当反斜线后面的字符有特殊含义时,反斜线将屏蔽特殊含义;当只有一个转义字符时,系统就会出现二级提示符,表示继续接受输入。执行脚本文件会提示出错;
转义符后面跟字母表示特殊有意义:但是要加上-e。如:echo -e “\t\a”;或者加上$'',效果一样,后者还可以进行变量赋值,如value=$'\t'  echo $value
\\反斜杠
\a警报,响铃
\b退格(删除键)
\f换页(FF),将当前位置移到下页开头
\n换行
\r回车
\t水平制表符(tab键) 
\v垂直制表符
使用echo命令的-E选项禁止转义;使用-n选项可以禁止插入换行符。

退出、测试、判断及操作符:
退出状态:
echo $? 可以输出上一条命令的输出状态
0:运行成功
1~125:运行失败,脚本命令、系统命令或参数传递错误
126:找到命令但是无法执行
127:未找到命令
>127:命令被系统强制结束
测试:
如果测试结果为真,则返回一个0值;如果为假返回一个非0值;格式为test 表达式;或者【表达式】;【表示启动测试的命令;不适用浮点树比较
整数比较运算符:
num -eq num:等于
num -ge num:大于或等于
num -gt num:大于
num -le num:小于或等于
num -lt num:小于
num -ne num:不等于
如: [ "$num" -eq 15 ]     echo $? 其中中括号两边都要有空格,用输出状态来观察执行结果
字符串运算符:
string:是否不为空;特殊性:不可以使用【】格式,只能是test string
-n string:是否不为空
-z string:是否为空
string1=string2:是否相同
string1!=string2:是否不相同
文件操作符:
-d file:是否为目录;如[-d input] echo $?
-e file:是否存在
-f file:是否为普通文件
-r file:是否是进程可读文件
-s file:长度是否不为0
-w file:是否进程可写文件
-x file:是否进程可执行文件
-L file:是否符号化链接
逻辑运算符:用于判断多个条件是否为真
!expression:如:[ ! -e 20150807-2.awk ]表示验证不存在这个文件
expression -a expression:同时为真则测试结果为真:[ -e 20150807-2.awk -a -r 20150807-2.awk ]验证孙在且可读
expression -o expression:有一个为真,则测试条件为真
判断:
简单if结构:if expression;then command ... command fi   if如果后面没有;then 需要换行
exit:设置退出状态值
if/else结构:
if/else语句嵌套:
case:找到匹配的值,没有默认执行*);知道;;为止
运算符:
+:加运算
-:减运算
*:乘运算
/:除运算
%:取余运算
**”幂运算
位运算符:
<<:左移,如:value=4<<2,表示4左移2位,为16
>>:右移
&:按位与
|:按位或
~:按位非
^:按位异或
自增自减运算符:前置自增自减(++value)先增减再赋值;后置自增自减(value--)先赋值再增减
数字变量:0作为前缀表示八进制;0x表示十六进制;也可以使用2#、8#、16#表示使用对应的进制
循环与架构化命令:
for循环:
列表for循环:执行次数同列表中常数或者字符串个数相同
如:for device in {1..5};do echo "$device hello";done;可以用..表示省略;也可以 for device in {1..5..2};do echo "$device hello";done;设定跳跃的步数;还可以for device in $(seq 1 5);do echo "$device hello";done;
也可以将常数换成字符串或者命令,如 ls等
不带列表for循环:由用户指定参数,仅限命令行传递参数
类C风格的for循环:同C很像,不同在于for带的括号是双层的,如for (())
while循环:
计数器控制的while循环:
结束标记控制的while循环:
标志控制的while循环:
until循环:

备注:
1.dirname $0:$0表示当前shell程序的文件名;dirname表示获取路径;dirname $0表示获取当前shell程序的当前路径;cd dirname $0表示进入这个路径;大部分时候这个命令的作用不太
2.sed 's/[[:space:]]//g'` #替换空格
3.xargs	是指将输入拆分成多个字符串,如删除文件时 xargs rm -f 有助于删除正常执行

你可能感兴趣的:(笔记)