一、入门
我们编写一个脚本程序,结尾一般要用sh
[root@node03 ~]# mkdir shell_test
[root@node03 ~]# cd shell_test/
[root@node03 shell_test]# vi wc.sh
#!/bin/bash
echo "hell0 spark"
[root@node03 shell_test]# chmod +x wc.sh
[root@node03 shell_test]# ./wc.sh
脚本里面的第一行#!/bin/bash加上之后,执行./命令才能识别,假如使用sh命令执行脚本文件,可以没有+x 和 第一行解释器#!/bin/bash
假如不是使用sh命令,那么需要+x 且 #!/bin/bash
执行结果:
[root@node03 shell_test]# ./wc.sh
hell0 spark
Shell的debug模式
我们可以在第一行的#!/bin/bash之后加上 -x 表明我们要执行debug模式 #!/bin/bash -x
[root@node03 shell_test]# vi shell_debug
#!/bin/bash -x
ll
echo "hello hadoop"
date
[root@node03 shell_test]# chmod +x shell_debug
[root@node03 shell_test]# ./shell_debug
+ ll
./shell_debug: line 2: ll: command not found
+ echo 'hello hadoop'
hello hadoop
+ date
Sat Apr 13 09:13:37 CST 2019
从上而下 一行行执行
二、变量定义和引用
[root@node03 shell_test]# vi variable.sh
#!/bin/bash
RZ='hello spark'
DATE=`date`
echo ${RZ}
echo ${DATE}
[root@node03 shell_test]# chmod +x variable.sh
[root@node03 shell_test]# ./variable.sh
hello spark
Sat Apr 13 09:17:43 CST 2019
注意: 单引号和双引号里面放的是字符串 echo${相关的常量} 而反引号` `里面放的是linux脚本命令(变量全部用大写)
静态变量【可以没有引号;可以单引号和双引号】
K=V 'V' "V"
动态变量【反斜杠引号】【比如TEST=`spark` echo ${TEST}指的是用户环境里的spark命令】[建议使用用户环境变量里的命令时候补全命令的路径(也就是安装目录下的bin目录下的此命令=全路径)]
K=`V`
=前后不能有空格
引用:【可以有{}也可以没有{}中括号】
$KA【这里的KA是一个变量】
${K}A 【这里的K是一个变量;A就是字母A】
三、传递参数
[root@node03 shell_test]# cat parameter.sh
#!/bin/bash
echo $1
echo $2
echo "个数:$#"
echo "参数作为一个长字符串:$*"
echo "PID: $$"
[root@node03 shell_test]# ./parameter.sh
个数:0
参数作为一个长字符串:
PID: 1130
[root@node03 shell_test]# ./parameter.sh 1 2
1
2
个数:2
参数作为一个长字符串:1 2
PID: 1131
[root@node03 shell_test]# ./parameter.sh jeff ruoze
jeff
ruoze
个数:2
参数作为一个长字符串:jeff ruoze
PID: 1132
PID: 1132【shell脚本执行的那一刹那的pid;执行完毕后pid就消失了】
$1代表第一个参数
$2代表第二个参数
shell脚本传递参数按照空格来分割
$#代表的是参数的个数
$*的*号代表把传递进来的参数作为长字符串输出
四、数组
shell里只支持一维的
[root@node03 shell_test]# chmod +x array.sh
[root@node03 shell_test]# cat array.sh
#!/bin/bash
arr=(hadoop spark hive hbase zookeeper)
echo ${arr[@]}
echo ${arr[*]}
echo ${arr[4]}
echo ${#arr[@]}
[root@node03 shell_test]# ./array.sh
hadoop spark hive hbase zookeeper
hadoop spark hive hbase zookeeper
zookeeper
5
数组以空格分割的
@和*表示输出数组中所有元素
[4]表示第五个元素 (下标从0开始)
#arr[@]表示数组的元素个数
五、if判断
[root@node03 shell_test]# chmod +x if.sh
[root@node03 shell_test]# cat if.sh
#!/bin/bash
A="spark"
B="hadoop"
if [ "${a}" == "$b" ];then
echo "=="
else
echo "!="
fi
[root@node03 shell_test]# ./if.sh
==
因为这里的a,b都不存在所以都是空的;所以输出的是==
注意 :==前后有空格,[ $a == $b ]
六、循环
[root@node03 shell_test]# chmod +x xunhuan.sh
[root@node03 shell_test]# cat xunhuan.sh
#!/bin/bash
j=0
for x in 1 2 3 4 5
do
echo $x
let "j++"
done
echo $j
echo "------------------"
for ((i=1;i<5;i++))
do
echo $i
done
echo "===================="
x=1
y=1
while(($y<5))
do
echo $y
let "y++"
let "x++"
done
echo "x: ${x}"
[root@node03 shell_test]# ./xunhuan.sh
1
2
3
4
5
5
------------------
1
2
3
4
====================
1
2
3
4
x: 5
let表示后面的值要进行运算
七、分割
[root@node03 shell_test]# chmod +x split.sh
[root@node03 shell_test]# cat split.sh
#!/bin/bash
S="spark,hadoop,hdfs,MR,hive,hbase"
OLD_IFS="$IFS"
IFS=","
arr=($S)
IFS="OLD_IFS"
for x in ${arr[*]}
do
echo $x
done
[root@node03 shell_test]# ./split.sh
spark
hadoop
hdfs
MR
hive
hbase
其中
OLD_IFS="$IFS"
IFS=","【分隔符】
arr=($S)【数组】
IFS="OLD_IFS"
是固定写法;将分割好的元素放入arr数组
八、awk
[root@node03 shell_test]# cat awk.txt
8 9 3
4 7 6
9 23 5
打印第一列
[root@node03 shell_test]# cat awk.txt |awk '{print $1}'
8
4
9
打印前两列
[root@node03 shell_test]# cat awk.txt |awk '{print $1 $2}'
89
47
923
让两列的数字分割开来
[root@node03 shell_test]# cat awk.txt |awk '{print $1,$2}'
8 9
4 7
9 23
[root@node03 shell_test]# cat awk.txt |awk '{print $1,$2}'后面的'' 不可以是双引号
[root@node03 shell_test]# cat awk.txt |awk -F " " '{print $2}'
9
7
23
打印行
[root@node03 shell_test]# cat awk.txt |awk -F " " 'NR==1'
8 9 3
[root@node03 shell_test]# cat awk.txt |awk -F " " 'NR==2'
4 7 6
[root@node03 shell_test]# cat awk.txt |awk -F " " 'NR>1'
4 7 6
9 23 5
具体操作看 awk --help
其中{print $1}表示打印第一列;{print $2}就是第二列;{print $0}是打印全部;
注意{print $1,$2}和{print $1 $2}表示第一和第二列;有逗号和没逗号是有区别的
九、sed 替换
将一个字母先替换掉
[root@node03 shell_test]# cat sed.log
q w e
1 2 3
[root@node03 shell_test]# sed -i 's/w/ww/' sed.log
[root@node03 shell_test]# cat sed.log
q ww e
1 2 3
将ww转换为www'
[root@node03 shell_test]# sed -i "s/ww/www'/" sed.log
[root@node03 shell_test]# cat sed.log
q www' e
1 2 3
将www'转换为bbb【将/换为?用是一样的】
[root@node03 shell_test]# sed -i "s?www'?bbb?" sed.log
[root@node03 shell_test]# cat sed.log
q bbb e
1 2 3
全局替换 g表示全局global
[root@node03 shell_test]# cat sed.log
q bbb e
1 2 3 e
[root@node03 shell_test]# sed -i 's/e/i/g' sed.log
[root@node03 shell_test]# cat sed.log
q bbb i
1 2 3 i
每行的行首前面加uuu
[root@node03 shell_test]# sed -i "s/^/uuu&/g" sed.log
[root@node03 shell_test]# cat sed.log
uuuq bbb i
uuu1 2 3 i
每行行尾后面加uuu
[root@node03 shell_test]# sed -i "s/$/&uuu/g" sed.log
[root@node03 shell_test]# cat sed.log
uuuq bbb iuuu
uuu1 2 3 iuuu