工作两年后,发现sheel脚本用的挺多,一直感觉自己用的还可以,后来才发现很多地方自己不够清楚,特写下这篇博客对用到的地方进行总结。
一、sheel加载的四种方式。
1、工作目录执行。
工作目录执行,指的是执行脚本时,先进入到脚本所在的目录(此时,称为工作目录),然后使用 ./脚本方式执行 [tan@tan scripts]$ ./test.sh -bash: ./test.sh: Permission denied [tan@tan scripts]$ chmod 764 test.sh [tan@tan scripts]$ ./test.sh Hello Shell 如图,报了权限错误,上一篇博文有提到,这里需要赋权,使用chmod 764 test.sh 赋权后就可以正常执行了 ./的意思是说在当前的工作目录下执行hello.sh。如果不加上./,bash可能会响应找到不到hello.sh的错误信息。
因为目前的工作目录 (/data/shell)可能不在执行程序默认的搜索路径之列,也就是说,不在环境变量PASH的内容之中。
查看PATH的内容可用 echo $PASH 命令。现在的/data/shell就不在环境变量PASH中的,所以必须加上./才可执行。
2、绝对目录执行。
绝对目录和工作目录执行没有本质的差别,都需要有可执行权限。
3、sh执行。
指的是用脚步对应的sh或bash来解析脚步执行。
[tan@tan scripts]$ sh test.sh Hello Shell [tan@tan scripts]$ bash test.sh Hello Shell 注意,若是以方法三的方式来执行,那么,可以不必事先设定shell的执行权限,甚至都不用写shell文件中的第一行(指定bash路径)。
因为方法三 是将hello.sh作为参数传给sh(bash)命令来执行的。这时不是hello.sh自己来执行,而是被人家调用执行,所以不要执
行权限。那么不用 指定bash路径自然也好理解了啊,呵呵……。
4、source和.执行。
指的是在当前的shell环境中执行,也需要有执行权限,但是相比前面三个不会创建一个子进程来执行。
[tan@tan scripts]$ . test.sh Hello Shell [tan@tan scripts]$ source test.sh Hello Shell
变量的传递总结如下链接:https://zhuanlan.zhihu.com/p/60761450
二、dirname和basename的使用
cur_dir=$(cd $(dirname $0);pwd) #获取当前路径 BASE_PARENT_DIR=$(dirname $cur_dir)#获取目录的上一级目录
basename /usr/bin/sort Output "sort". basename include/stdio.h .h Output "stdio".
三、echo
echo <和echo <<的作用
echo > 是输出重定向 echo >> 输出追加重定向
> /dev/null 2>&1 1和2都输出到黑洞
echo 的显示
-n do not output the trailing newline -e enable interpretation of backslash escapes -E disable interpretation of backslash escapes (default)
https://blog.csdn.net/xnn_1993/article/details/87090754
四、sed
sed表示Stream Editor,流式编辑器又名行编辑器,每次编辑一行,它可以执行各种功能,如搜索、查找、修改、插入或删除文件,此外,他也可以
执行复制的正则表达式匹配。它可以用于以下目的:
- 查找和替换匹配给定的格式的内容
- 在指定行查找和替换匹配给定格式的内容
- 在所有行查找和替换匹配给定格式的内容
- 搜索并同时替换两种不同的模式
使用的格式如下:sed [操作选项] ‘命令’ 文件名,
常用的操作选项如下:
-n:指定处理后只显示该行 -e:进行多项编辑任务 -i:直接修改读取的文件内容,而不是由屏幕输出。
-f 该选项会将其后文件中的脚步命令添加到已有的命令中。
常用的命令选项如下:
p:打印匹配行
a:新增
c:替代一行
d:删除定位行
s:替代一行中的某些部分
g:全局替换标志
n:1-512之间的数字,表示出现第几次替换。
正则表达式:
1、符号".": 匹配任意一个字符,除了换行符,但是需要注意的是,在sed中不能匹配换行符,但是在awk中可以匹配换行符。类似shell通配符中的"?",匹配一个任意字符。 2、符号"*": "*"表示前边字符有0个或多个。".*"表示任意一个字符有0个或多个,也就是能匹配任意的字符。类似shell通配符中的"*",可以匹配任意字符。 3、 符号"[]": "[ ]"中括号中可以包含表示字符集的表达式。使用方法大概有如下几种。 [a-z]:表示a-z字符中的一个,也就是小写字母。 [0-9]:表示0-9字符中的一个,也就是表示数字。 [A-Z]:表示大写字母。 [a-zA-Z]:表示字符集为小写字母或者大写字母。 [a-zA-Z0-9]:表示普通字符,包括大小写字母和数字。 [abc]:表示字符a或者字符b或者字符c。 [^0-9]:表示非数字类型的字符,^表示取反意思,只能放在中括号的开始处才有意义。 [-cz]:表示字符-或者字符c或者字符z,注意与[c-z]的区别,因为-符号没有放在e和f之间。 4. 符号"^": ^"表示行首的意思,也就是每一行的开始位置。在这里并不是上边字符范围中取反的意思,^符号只有在"[]"符号的开头处才能表示字符取反。 ^abc:表示以abc开头的字符串abc。 ^abc.*:表示以abc开头的字符串abcxxx。 5. 符号"$" "$"表示行尾的意思,也就是每一行的结尾位置,很好理解,和"^"正好相反。 world$:表示以world结尾的字符串world,如果该行中间有world字符串是不符合匹配条件的。 ^$:表示空行。行首和行尾没有内容,可不就是空行嘛。 6. 符号"": ""表示是转义字符,和其它语言中用到的转义字符意义基本上是一样的。其实简单理解,就是把元字符转义为普通字符,比如"\"表示普通符号"",把普通字符转换为特殊意义符号,比如" "表示把普通字符n转义为换行符。 7. 符号"{}": "{}"表示前边字符的数量范围,大概有三种用法,其实容易理解,看例子就知道了,但是必须注意要加上转义字符"",否则不生效,表示为普通字符"{"或"}"。 {2}:表示前边字符的重复次数是2。 {2,}:表示前边字符的重复次数至少是2,也就是大于等于2。 {2,9}:表示前边字符的重复次数大于2但小于9。 8. 符号"<"和">": "<"表示匹配条件为词首的位置,理解上可以对比 "^" 行首。 举个例子,"nihao 1hello 2hello3 hello4"有这么内容的一行内容。 "<hello"匹配结果"nihao 1hello 2hello3 hello4"; "hello>"匹配结果"nihao 1hello 2hello3 hello4",这种匹配方式用的不是太多,用到会用就OK
使用例子:
1、显示 sed -n '2p' tmp.txt 只显示第二行 sed -n '1,3p' tmp.txt 打印第一行到第三行 sed -n '/mov/p' tmp.txt 打印含mov的行
sed -n "/kevin/,/frank/"p tmp.txt 打印匹配kevin开始,frank为结束的行
2、删除
sed '2d' tmp.txt 删除第二行 sed '3,$d' tmp.txt 删除第三行到最后一行,$表示最后一行 3、查询 sed -n '/hello/p' tmp.txt查询包含关键字hello的所有行 4、代替 sed '1c Hi' tmp.txt 第一行替代为Hi
sed '/tom/c Hi' tmp.txt 仅仅替换有tom的行 sed -n '/hello/p' tmp.txt | sed 's/hello/bid/g'把hello替换bird
sed 's/to/tt/2' tmp.txt 只替换第2个to
sed 's/^/// comment /' tmp.txt开头加点注释
sed 's/$/// comment /' tmp.txt末尾加点注释
sed -i /^servial/c"hello" tmp.txt 以serial开头的行替换为hello
5、插入 sed -i '$a bye' tmp.txt 在最后一行插入bye
sed -i 3d tmp.txt 可以看到命令不一定非要用‘’
五、awk
awk是一个强大的文本分析工具,它把文件逐行的读入,以空格为默认分割符将每行分割为多个字段。
使用方式:awk [OPTIONS] ‘pattern {action}’ filenames,其中pattern是要查找的内容(可以没有,也叫匹配的规则),action找到匹配内容时所执行的命令
last -n 5 | awk '{print $1}' 列出最近五个登录用户 cat /etc/passwd | awk -F ':' '{print $1}' awk -F ':' '$1=="root" {print $0}' /etc/paswd -F指定分隔符,$0表示整行,$1表示第一列,条件后有空格
awk -F 'a|b' '{}'或者awk -F '[a|b]' '{}'以a或者b作为分割符,和awk -F "[ab]" '{}'作用一样
awk -F "[a][b]" '{}'这种形式的分隔符是合并的关系,即以ab作为一个字符分割
awk中两个特别的表达式,BEGIN和END,都可以用于pattern中,在程序赋予初始状态和程序结束之后的一些扫尾工作
awk -F, ‘BEGIN{sum=0}{sum==$3}END{print sum/1024/1024" GB"}'