前言:
shell脚本就是常用的date ,pwd,cd等命令堆积在一起的文本格式
1.入门
shell脚本约定的后缀是.sh(非必需)
第一行的#!/bin/bash为解释器(非必需) # linux /bin目录下的bash去执行
假如使用sh命令执行脚本文件,可以没有+x 和 第一行解释器#!/bin/bash #sh ./test.sh
假如不是使用sh命令,那么需要+x 且 #!/bin/bash #赋权限chmod -x test.sh 然后全路径执行 /root/shell/test.sh或者相对路径执行./test.sh
shell脚本的debug模式(可以迅速看代码符文准确) -x
[root@hadoop-01 ~]# cat test.sh
#!/bin/bash -x
echo "www.baidu.com"
ls -l
pwd
[root@hadoop-01 ~]# chmod +x test.sh
[root@hadoop-01 ~]# ./test.sh
+ echo www.baidu.com
www.baidu.com
+ ls -l
total 8
drwxr-xr-x 2 root root 4096 Mar 28 20:41 software
-rwxr-xr-x 1 root root 49 Apr 13 11:03 test.sh
+ pwd
/root
[root@hadoop-01 ~]#
2.变量定义和引用
[root@hadoop-01 ~]# vi variable.sh
#!/bin/bash
RZ='www.baidu.com'
DATE=`date`
echo ${RZ}
echo ${DATE}
注意:
静态变量 K=V 'V' "V" #后面的字符串不用引号、用单引号或者双引号都可以
动态变量 K=`V` # 用反引号,反引号内要是能执行成功的命令,除linux自带的命令外,其他系统依赖的命令确实有的话还是不能执行就输入绝对路径
=前后不能有空格
变量一律用大写
引用变量: 标准${K} #如果写成$KA ,找不到这个变量的话,出来就是空格 ;${K}A 代表在引用变量K后拼接一个字母A
linux下执行报错显示第几行时可以用set nu命令去定位
3.传递参数
[root@hadoop-01 shell]# cat parameter.sh
#!/bin/bash
echo $1
echo $2
echo "个数:$#"
echo "参数作为一个长字符串: $*"
echo "PID: $$"
[root@hadoop-01 shell]# chmod +x parameter.sh
[root@hadoop-01 shell]# ./parameter.sh
个数:0
参数作为一个长字符串:
PID: 12972 #shell脚本执行的那一刹那的pid;执行完毕后pid就消失了
[root@hadoop-01 shell]# ./parameter.sh a b #传递a,b这连个参数,所以个数会变为2
a
b
个数:2
参数作为一个长字符串: a b
PID: 12889
[root@hadoop-01 shell]#
如何过滤掉PID: 12972
[root@hadoop-01 shell]# ps -ef|grep 12972
root 12976 12271 0 11:31 pts/0 00:00:00 grep 12972
[root@hadoop-01 shell]# ps -ef|grep 12972 |grep -v grep #加上|grep -v grep就会忽略捕获自己
4.数组
[root@hadoop-01 shell]# cat array.sh
#!/bin/bash
arr=(a b c d e f) # 空格分隔
echo ${arr[@]}
echo ${arr[*]}
echo ${arr[4]} #从0,1,2,3,4,5开始
echo ${#arr[@]}
[root@hadoop-01 shell]# chmod +x array.sh
[root@hadoop-01 shell]# ./array.sh
a b c d e f
a b c d e f
e
6
[root@hadoop-01 shell]#
注意:
数组只支持一维的
[@]和[*]一样表示输出数组中所有元素
[4]表示第五个元素 ,从0开始
[@]表示数组的元素个数
5.if判断
[root@hadoop-01 shell]# cat if.sh
#!/bin/bash
A="abc"
B="leo"
if [ $a == $b ];then
echo "=="
else
echo "!="
fi
[root@hadoop-01 shell]# chmod +x if.sh
[root@hadoop-01 shell]# ./if.sh
==
[root@hadoop-01 shell]#
注意:
这里的a,b是小写,之前定位的变量是大写,所以都不存在,都是空的,输出的是==
[root@hadoop-01 shell]# cat if.sh
#!/bin/bash
A="abc"
B="leo"
if [ $A == $B ];then
echo "=="
else
echo "!="
fi
[root@hadoop-01 shell]# ./if.sh
!=
[root@hadoop-01 shell]#
修改后输出的就是!=
elif
[root@hadoop-01 shell]# cat if.sh
#!/bin/bash
A="abc"
B="leo"
if [ $A == $B ];then
echo "=="
elif [ $A == "abc" ];then #等价于elseif
echo "abc here"
else
echo "!="
fi
[root@hadoop-01 shell]# ./if.sh
abc here
[root@hadoop-01 shell]#
规则:
==前后有空格 ,[ $A == $B ]
6.循环
[root@hadoop-01 shell]# cat ifwhile.sh
#!/bin/bash
j=0
for x in 1 2 3 4 5
do
echo $x
let "j++"
done
echo $j
echo "------------------" #for循环
for ((i=1;i<5;i++))
do
echo $i
done
echo "-----------------" #while循环
x=1
y=1
while(($y<5))
do
echo $y
let "y++"
let "x++"
done
echo "x: ${x}"
[root@hadoop-01 shell]# chmod +x ifwhile.sh
[root@hadoop-01 shell]# ./ifwhile.sh
1
2
3
4
5
5
------------------
1
2
3
4
-----------------
1
2
3
4
x: 5
[root@hadoop-01 shell]#
注意:
j++ ==》j=j+1
7.分割
[root@hadoop-01 shell]# cat split.sh
#!/bin/bash
S="a,b,c,d,e,f,g,h"
OLD_IFS="$IFS"
IFS=","
arr=($S)
IFS="OLD_IFS"
for x in ${arr[*]}
do
echo $x
done
[root@hadoop-01 shell]# chmod + split.sh
[root@hadoop-01 shell]# ./split.sh
-bash: ./split.sh: Permission denied
[root@hadoop-01 shell]# cat split.sh
#!/bin/bash
S="a,b,c,d,e,f,g,h"
OLD_IFS="$IFS"
IFS="," #分割符
arr=($S) #变量
IFS="OLD_IFS"
for x in ${arr[*]}
do
echo $x
done
[root@hadoop-01 shell]# chmod +x split.sh
[root@hadoop-01 shell]# ./split.sh
a
b
c
d
e
f
g
h
[root@hadoop-01 shell]#
8.awk取数
[root@hadoop-01 shell]# cat awk.log |awk '{ print $1 }'
a,b,c
1,2,3
4,5,6
[root@hadoop-01 shell]# awk '{ print $1 }' awk.log
a,b,c
1,2,3
4,5,6
#以上的两种写法都一样,但是如果一个文件内容很多,用cat这种方式就不好了
[root@hadoop-01 shell]# cat awk.log |awk -F "," '{ print $1 }'
a
1
4
[root@hadoop-01 shell]# cat awk.log |awk -F "," '{ print $3 }'
c
3
6
[root@hadoop-01 shell]# cat awk.log |awk -F "," 'NR>1{ print $3 }'
3
6
[root@hadoop-01 shell]#
注意:
{print $1 $2}‘和’{print $1,$2}'区别(面试题)
‘{print $1 $2}’:表示先取第一列,然后取第二列。数据在文本中什么格式打印出来就是什么格式
‘{print $1,$2}’:表示先取第一行第一列,再取第一行第二列,再取第二行第一列
9.sed替换
[root@hadoop-01 shell]# sed -i 's/a/aa/' sed.log
[root@hadoop-01 shell]# cat sed.log
aaa b c
1 2 3
[root@hadoop-01 shell]# sed -i "s/aa/aa'/" sed.log #里面有'外面就用"
[root@hadoop-01 shell]# cat sed.log
aa'a b c
1 2 3
[root@hadoop-01 shell]# sed -i "s?aa'?bbb?" sed.log #自定义替换
[root@hadoop-01 shell]# cat sed.log
bbba b c
1 2 3
[root@hadoop-01 shell]# sed -i "s/b/w/" sed.log #只能替换每行的第一个
[root@hadoop-01 shell]# cat sed.log
wbba b c
1 2 3
[root@hadoop-01 shell]#
全局替换
[root@hadoop-01 shell]# sed -i "s/b/w/g" sed.log #globle全局
[root@hadoop-01 shell]# cat sed.log
wwwa w c
1 2 3
[root@hadoop-01 shell]#
每行行首加
[root@hadoop-01 shell]# sed -i "s/^/uuu&/g" sed.log
[root@hadoop-01 shell]# cat sed.log
uuuwww w c
uuu1 2 3
每行行尾加
[root@hadoop-01 shell]# sed -i "s/$/&uuu/g" sed.log
[root@hadoop-01 shell]#
[root@hadoop-01 shell]# cat sed.log
uuuwww w cuuu
uuu1 2 3uuu
[root@hhadoop-01 shell]#