1 shell
它是一门解释型语言,一般叫做脚本或shell脚本
1.1 分类
ksh
tcsh
sh
bash
查看系统支持的shell
/etc/shells
查看当前使用shell
echo $SHELL
1.2 数据类型
字符型:
'sads' '1233' "jhsdajks"
数值型:
123 1 2 3 5
1.3 shell变量
变量:一段被命名的内存空间
变量名:
一般具有实际意义的单词缩写
不能以关键字或特殊字符作为变量
不能以数字开头作为变量
定义变量:
variable_name=value
aa='123'
bb=123
变量分类:
环境变量:全系统都能使用的变量
printenv,env
定义环境变量export variable_name=value
在shell当中直接定义只在当前shell终端窗口生效
永久生效:/etc/profile
某用户生效:~/.bashrc
局部变量:
定义:aa=123
在shell当中直接定义只在当前shell终端窗口生效
或者只在脚本内生效
特殊变量:
$?:表示上一条执行指令的返回状态码,0 正常 ,否则不正常
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 cd /etc
9 echo $?
[root@wzlvm test]# sh test1.sh
0
$n:n表示整数,$1表示脚本后面所跟的第一个参数
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 echo $1
9 echo $2
10 echo $3
[root@wzlvm test]# sh test1.sh 1 22 4
1
22
4
$0:表示脚本名称
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 echo $0
[root@wzlvm test]# sh test1.sh
test1.sh
$#:所有参数的个数
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 echo $#
[root@wzlvm test]# sh test1.sh 1 2 3 3
4
$*:列出所有的参数
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 echo $*
[root@wzlvm test]# sh test1.sh 1 2 3 3
1 2 3 3
$@:列出所有的参数
$$:查看脚本执行时的进程号
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 echo $$
[root@wzlvm test]# sh test1.sh 1 2 3 3
1924
运算符:
数值运算符:
+:加
-:减
*:乘
/:商取整 10/3 3
%:取余 10%3 1
**:取幂 10**3 1000
[root@wzlvm test]# echo `expr 2 + 3`
5
[root@wzlvm test]# echo `expr 2 * 3`
expr: syntax error
[root@wzlvm test]# echo `expr 2 \* 3`
6
[root@wzlvm test]# echo `expr 2 / 3`
0
[root@wzlvm test]# echo `expr 2 - 3`
-1
[root@wzlvm test]# echo `expr 3 % 2`
1
[root@wzlvm test]# echo `expr 5 % 2`
1
布尔值预算符:
&&:与运算
||:或运算
!:非运算
关系运算符:
$aa和$$bb是数值
>:大于 [ $aa -gt $bb ]
<:小于 [ $aa -lt $bb ]
<=:小于等于 [ $aa -le $bb ]
>=:大于等于 [ $aa -ge $bb ]
==:等于 [ $aa -eq $bb ]
!=:不等于 [ $aa -ne $bb ]
[root@wzlvm test]# if [ 1 -gt 2 ];then
> echo 'ok'
> else
> echo 'error'
> fi
error
[root@wzlvm test]# if [ 1 -lt 2 ];then
> echo 'ok'
> else
> echo 'error'
> fi
ok
1.4 shell语法:
第一行必须以#!/bin/bash作用指定解释器 必要
最好有缩进习惯 非必要
要有注释信息 非必要
打印:
#!/bin/bash
#
#
echo "hello world"
echo 'hello world'
"":弱引用 echo "$aa" 引用的是aa变量的值
'':强引用 echo '$aa' 就是打印$aa
echo -e '\t'打印一个制表符
printf "username:%s uid:%d" $user $uid
格式化输出
%s字符变量占位符
%d整数变量占位符
%f浮点变量占位符
%cASCII变量占位符
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 printf "username:%s uid:%d\n" 'wzl' 33
[root@wzlvm test]# sh test1.sh
username:wzl uid:33
命令替换:
`command`:tab键上面的那个符号,专业一点叫做反引号
a=`date`:表示把变量名a的作用变为date指令
[root@wzlvm test]# tmp=`ls -l`
[root@wzlvm test]# echo $tmp
total 4 -rw-r--r-- 1 root root 0 Oct 26 19:34 2 -rw-r--r-- 1 root root 92 Oct 26 19:40 test1.sh
1.5 循环:
for 变量 in 范围
do
代码块
done
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 for i in {1..10}
9 do
10 echo $i
11 done
[root@wzlvm test]# sh test1.sh
1
2
3
4
5
6
7
8
9
10
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 array=(1 2 4 8 5)
9 for i in ${array[*]}
10 do
11 echo $i
12 done
[root@wzlvm test]# sh test1.sh
1
2
4
8
5
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 for i in {1..5}
9 do
10 for j in {6..10}
11 do
12 printf "$i\t$j\n"
13 done
14 done
[root@wzlvm test]# sh test1.sh
1 6
1 7
1 8
1 9
1 10
2 6
2 7
2 8
2 9
2 10
3 6
3 7
3 8
3 9
3 10
4 6
4 7
4 8
4 9
4 10
5 6
5 7
5 8
5 9
5 10
while循环:
while 条件
do
代码块
done
当条件为真的时候执行代码块
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7 i=0
8 while [ $i -lt 10 ]
9 do
10 echo $i
11 let i++
12 done
[root@wzlvm test]# sh test1.sh
0
1
2
3
4
5
6
7
8
9
跳出循环:
break:跳出当前循环体
continue:跳出本次循环
exit:推出循环程序
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 i=2
9 while true
10 do
11 echo $i
12 tmp=$[i%5]
13 if [ $tmp -eq 1 ];then
14 break
15 fi
16 let i++
17 done
# 上面break 跳出循环
[root@wzlvm test]# sh test1.sh
2
3
4
5
6
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 i=2
9 while true
10 do
11 echo $i
12 let i++
13 tmp=$[i%5]
14 if [ $tmp -eq 1 ];then
15 echo '------------'
16 sleep 5
17 continue
18 fi
19 done
[root@wzlvm test]# sh test1.sh
2
3
4
5
------------
6
7
8
9
10
[root@wzlvm test]# vim test1.sh
1 #!/bin/bash
2 #
3 #
4 #
5 # Aut wangzilong
6 # Shell Document
7
8 i=2
9 while true
10 do
11 echo $i
12 let i++
13 tmp=$[i%5]
14 if [ $tmp -eq 1 ];then
15 echo '------------'
16 exit
17 fi
18 done
[root@wzlvm test]# sh test1.sh
2
3
4
5
------------
[root@wzlvm test]#
2 正则表达式:
是一组具有匹配模式的特殊字符集合
过滤匹配的字符,搜索关键字,匹配关键行
字符:
[]
[^]
.
次数:
*
?
+
{m,n}
{0,}====>*
定界(锚定)
^
$
引用:
()
[a-z]:表示26个小写字母
[A-Z]:表示26个大写字母
[0-9]:表示数字0-9
[@_....]:表示@符号_下划线...省略号
[\*]:只表示*号字符不是正则当中的*号也不是通配符
^#:匹配以#开头的内容
end$:匹配以end结尾的内容
^$:表示空白行
^#end$:匹配以#开头以end结尾的内容
a.a:表示三个字符第一个是a最后一个是a中间任意字符
a*a:表示至少一个a或者是a任意字符a,a,aaaa,aaaaaa.*a:表示axxxa,adhsddjksda
\d:表示数字0-9
\w:[a-zA-Z0-9_]
\s:任意空白字符
\n:换行
\t:制表符
\r:回车符
3 sed 流媒体
sed [options] 'script' File
options:
-n:静默模式不输出模式空间当中的内容
-e:可以使用多个'script'
-r:支持扩展正则表达式
-f:指定sed脚本文件位置
-i:直接编辑原文件
地址定界:
/pat1/,/pat2/:表示匹配pat1的行到匹配pat2行之间所有行
/patter/:匹配pattern的行
startline,endline
1,3
$:最后一行
编辑指令:
d:删除
[root@wzlvm test]# sed '1,10d' /etc/fstab
UUID=ca988a6f-653c-4b64-b492-8cf71352dd27 swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/sdb1 /data/sdb1 ext4 defaults 0 0
/dev/cdrom /data/local_cdrom iso9660 defaults 0 0
# 上面已经删除了第1行到第10行
p:打印
[root@wzlvm test]# sed -n '10,13p' /etc/fstab
UUID=4a73926d-e60a-4ac1-a323-4b2bf4829433 /boot ext4 defaults 1 2
UUID=ca988a6f-653c-4b64-b492-8cf71352dd27 swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
# 由于sed本来会打印一次,p再打印一次,会重复打印,所以这个用-n 静默模式
a \text:在匹配内容之后插入
[root@wzlvm test]# sed '/^#$/a \今天是星期四' /etc/fstab
#
今天是星期四
# /etc/fstab
# Created by anaconda on Sat Sep 24 10:27:25 2016
#
今天是星期四
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
今天是星期四
UUID=62bf0c12-0292-4534-9947-9bd30ebd5d0f / ext4 defaults 1 1
UUID=4a73926d-e60a-4ac1-a323-4b2bf4829433 /boot ext4 defaults 1 2
UUID=ca988a6f-653c-4b64-b492-8cf71352dd27 swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/sdb1 /data/sdb1 ext4 defaults 0 0
/dev/cdrom /data/local_cdrom iso9660 defaults 0 0
# 上面在单个#的下一行添加 今天是星期四
i \text:在匹配内容之前插入
i 在上面插入,和上面的例子类似。这里就不举例了。
w:匹配的内容输出到一个文件
[root@wzlvm test]# sed -n '10,15w /tmp/123.txt' /etc/fstab
[root@wzlvm test]# cat /tmp/123.txt
UUID=4a73926d-e60a-4ac1-a323-4b2bf4829433 /boot ext4 defaults 1 2
UUID=ca988a6f-653c-4b64-b492-8cf71352dd27 swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
# 上面的例子匹配的行已经写入到/tmp/123.txt
r:在匹配的内容插入另外一个文件的所有内容
r 和上面的w类似,就不举例了。
s:/// @查找的内容@替换的内容@修饰符
[root@wzlvm test]# sed 's@#@###@g' /etc/fstab
###
### /etc/fstab
### Created by anaconda on Sat Sep 24 10:27:25 2016
###
### Accessible filesystems, by reference, are maintained under '/dev/disk'
### See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
###
UUID=62bf0c12-0292-4534-9947-9bd30ebd5d0f / ext4 defaults 1 1
UUID=4a73926d-e60a-4ac1-a323-4b2bf4829433 /boot ext4 defaults 1 2
UUID=ca988a6f-653c-4b64-b492-8cf71352dd27 swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/sdb1 /data/sdb1 ext4 defaults 0 0
/dev/cdrom /data/local_cdrom iso9660 defaults 0 0
# 上面的搜索替换已经被# 换成了###
=:打印匹配内容的行号
[root@wzlvm test]# sed -n '10,15=' /etc/fstab
10
11
12
13
14
15
4 awk
报表生成工具
awk [options] 'script' file
awk [options]{action} file
options:
-F:制定分割符
/pat1/,/pat2/
/patter/
expression
BEGIN....
END...
NF:字段数
FS:读入分割符默认为空白
OFS:输出分割符默认为空白
打印文件的第一列,以冒号分割的
awk -F ":" '{print $1}' /etc/passwd
打印以#开头的第一列
[root@wzlvm ~]# awk '/^#/{print $1}' /etc/fstab
#
#
#
#
#
#
#
打印文件的第一列,以冒号分割的
[root@wzlvm ~]# sed -n '1,10p' /etc/passwd|awk 'BEGIN{FS=":"}{print $1}'
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
uucp
对第一列前加上username:,第三列前加上uid:
[root@wzlvm ~]# sed -n '1,10p' /etc/passwd|awk -F ":" '{print "username:"$1,"uid:"$3}'
username:root uid:0
username:bin uid:1
username:daemon uid:2
username:adm uid:3
username:lp uid:4
username:sync uid:5
username:shutdown uid:6
username:halt uid:7
username:mail uid:8
username:uucp uid:10
/etc/passwd打印uid大于500的用户名
[root@wzlvm ~]# awk -F ":" '$3>500{print $1,$3}' /etc/passwd
user2 501
user3 502
user4 503
nfsnobody 65534
test1 504
t1 505
t2 506
d1 507
userftp 508
打印/etc/passwd 中无法登录的用户名和uid
[root@wzlvm ~]# awk -F "\/" '{print $1,$NF}' /etc/passwd|sed -n '/nologin/p'|awk -F ":" '{print $1,$NF}'|sed -n '1,10p'
awk: warning: escape sequence `\/' treated as plain `/'
bin nologin
daemon nologin
adm nologin
lp nologin
mail nologin
uucp nologin
operator nologin
games nologin
gopher nologin
ftp nologin