- shell文件行业规范默认后缀为.sh
- shell首行为#!/bin/bash,注意/bin/bash为当前脚本解释器,可以不写但不能写错了。
- #表示注释
- shell对大小写敏感,变量尽量全大写,小写会被鄙视
全局生效,通过set命令查看,用户环境变量,当前用户生效,系统环境变量,所有用户生效,通过export声明变量。
将脚本的参数传给脚本,多个参数使用空格隔开
$0:脚本文件名称
$1、$2…$9 :执行脚本的参数
[root@hadoop001 scripts]# cat shellTest.sh
#!/bin/bash
echo "$0"
echo "$1"
echo "$2"
echo "$3"
[root@hadoop001 scripts]# sh shellTest.sh start a b
shellTest.sh
start
a
b
由系统保留和维护的一组特殊变量
$0:代表当前脚本的名称
$!:后台运行的最后一个进程的PID
$?:上一个命令退出的状态(0:成功,非0:失败)
$*:当前shell参数集合(整体)
$$:表示当前进程ID号码
$#:代表当前shell的参数个数
$@:当前shell参数集合(逐个读取)
$? 上一个命令退出的状态(0:成功,非0:失败)
[root@hadoop001 scripts]# ll
total 584508
-rw-r--r--. 1 root root 598528000 Jan 1 06:01 mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar
drwxr-xr-x. 2 root root 4096 Apr 14 09:15 mysqlrpm
-rw-r--r--. 1 root root 53 Apr 15 10:55 shellTest.sh
[root@hadoop001 scripts]# echo $?
0
[root@hadoop001 scripts]# lll
-bash: lll: command not found
[root@hadoop001 scripts]# echo $?
127
$# 代表当前shell的参数个数
[root@hadoop001 scripts]# cat shellTest.sh
#!/bin/bash
echo "$#"
[root@hadoop001 scripts]# sh shellTest.sh first second third
3
$* 当前shell参数集合(整体)
[root@hadoop001 scripts]# cat shellTest.sh
#!/bin/bash
echo "$*"
[root@hadoop001 scripts]# sh shellTest.sh first second third
first second third
@表当前shell参数集合(逐个读取),不加引号和*一样,加了则在表示内一个参数
[root@hadoop001 scripts]# cat shellTest.sh
#!/bin/bash
test(){
echo "未添加引号"
echo $*
echo $@
echo "添加了引号"
for N in "$*"
do
echo $N
done
echo "----------------"
for N in "$@"
do
echo $N
done
}
test 1 2 3 4 5 6
[root@hadoop001 scripts]# sh shellTest.sh
未添加引号
1 2 3 4 5 6
1 2 3 4 5 6
添加了引号
1 2 3 4 5 6
----------------
1
2
3
4
5
6
$$:表示当前进程ID号
[root@hadoop001 scripts]# cat shellTest2.sh
#!/bin/bash
echo $$
[root@hadoop001 scripts]# sh shellTest2.sh
3274
[root@hadoop001 scripts]# sh shellTest2.sh
3275
[root@hadoop001 scripts]# sh shellTest2.sh
3276
shell文件默认是无执行权限,编辑完成可添加执行权限:chmod +x shellFile,或 sh shellFile 或 bash shellFile 或 source shellFile 或. shellFile来执行脚本
1.语法格式:变量名=变量值
2.注意:
1、等号两边不能有空格
2、变量名大小写敏感,官方建议大写,变量取值: 变 量 名 或 变量名 或 变量名或{变量名}3.用例:
[root@hadoop001 scripts]# param=3 [root@hadoop001 scripts]# echo ${param} 3
运算符:+ - * / %
语法:
( ( e x p r e s s i o n ) ) 或 ((expression)) 或 ((expression))或[expression] 或expr expression
用例:
[root@hadoop001 scripts]# echo $((5+5)) 10 [root@hadoop001 scripts]# echo $[5+5] 10 [root@hadoop001 scripts]# expr 5+5 5+5 [root@hadoop001 scripts]# expr 5 + 5 10
*注意:expr运算的变量间有无空格差别很大
语法:
test 测试表达式 或 [ 测试表达式 ]
用例:
[root@hadoop001 scripts]# a=2 [root@hadoop001 scripts]# b=3 [root@hadoop001 scripts]# [ $a -lt $b ] [root@hadoop001 scripts]# echo $? 0 [root@hadoop001 scripts]# [ $a -ge $b ] [root@hadoop001 scripts]# echo $? 1
*注意:测试表达式与[]之前必须有空格
语法:
-eq 等于,equal
-ne 不等于,not equal
-gt 大于,greate than
-ge 大于等于,greate than or equal
-lt 小于,less than
-le 小于等于,less than or equal用例:
[root@hadoop001 scripts]# a=2 [root@hadoop001 scripts]# b=3 [root@hadoop001 scripts]# [ $a -lt $b ] [root@hadoop001 scripts]# echo $? 0 [root@hadoop001 scripts]# [ $a -ge $b ] [root@hadoop001 scripts]# echo $? 1
语法:
= 等于
!= 不等于
-z 长度为零,如: [ -z “ m y v a r " ] − n 度 为 零 , 如 : [ − n " myvar" ] -n 度为零,如: [ -n " myvar"]−n度为零,如:[−n"myvar” ]用例:
[root@hadoop001 scripts]# a="aa" [root@hadoop001 scripts]# b="ab" [root@hadoop001 scripts]# c="aa" [root@hadoop001 scripts]# [ a = b ] ; echo $? 1 [root@hadoop001 scripts]# [ a = c ] ; echo $? 1 [root@hadoop001 scripts]# [ $a = $b ] ; echo $? 1 [root@hadoop001 scripts]# [ $a = $c ] ; echo $? 0 [root@hadoop001 scripts]# [ "$a" = "$b" ] ; echo $? 1 [root@hadoop001 scripts]# [ "$a" = "$c" ] ; echo $? 0 [root@hadoop001 scripts]# [ -z "$a" ] [root@hadoop001 scripts]# echo $? 1 [root@hadoop001 scripts]# [ -z "" ] ; echo $? 0
注意:
1、字符串比较时可以用=也可以用==,左右离比较符必须有空格
2、等于“=”不仅可以用来比较字符串也可以比较数字,注意要有空格,否则就是赋值了。
语法:
-e 文件名,文件存在为真
-r 文件名,文件存在且可读为真
-w 文件名,文件存在且可写为真
-x 文件名,文件存在且可执行为真
-s 文件名,文件存在且有一个字符为真
-d 文件名,文件存在且为目录为真,目录ll显示为d
-f 文件名,文件存在且为普通文件为真,普通文件类型为-
-c 文件名,文件存在且为字符串型特殊文件为真,几乎不用使用到。ll /dev/ 可查看c类型文件用例:
[root@hadoop001 scripts]# [ -f shellTest.sh ] ; echo $? 0 [root@hadoop001 scripts]# [ -d shellTest.sh ] ; echo $? 1
常用逻辑运算符:
代表命令行之间的关系
&&:命令与,
||:命令或
; :命令先后关系
-a:逻辑与
-o:逻辑或
! :逻辑非
&&:命令与,cmd1 && cmd2 ,第一个命令成功后执行第二个命令
[root@hadoop001 scripts]# ll /opt/scripts/ && sh shellTest2.sh total 584512 -rw-r--r--. 1 root root 598528000 Jan 1 06:01 mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar drwxr-xr-x. 2 root root 4096 Apr 14 09:15 mysqlrpm -rw-r--r--. 1 root root 20 Apr 15 11:08 shellTest2.sh -rw-r--r--. 1 root root 186 Apr 15 11:05 shellTest.sh 3312 [root@hadoop001 scripts]# ll /opt/script/ && sh shellTest2.sh ls: cannot access /opt/script/: No such file or directory
||:命令或,cmd1 || cmd2 ,第一个命令失败后执行第二个命令,不失败不执行
[root@hadoop001 scripts]# ll /opt/script/ || sh shellTest2.sh ls: cannot access /opt/script/: No such file or directory 3315 [root@hadoop001 scripts]# ll /opt/scripts/ || sh shellTest2.sh total 584512 -rw-r--r--. 1 root root 598528000 Jan 1 06:01 mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar drwxr-xr-x. 2 root root 4096 Apr 14 09:15 mysqlrpm -rw-r--r--. 1 root root 20 Apr 15 11:08 shellTest2.sh -rw-r--r--. 1 root root 186 Apr 15 11:05 shellTest.sh
; :命令顺序关系,cmd1 ;cmd2;cmd3,仅仅表示先后顺序
[root@hadoop001 scripts]# ll /opt/scripts/ ; sh shellTest2.sh total 584512 -rw-r--r--. 1 root root 598528000 Jan 1 06:01 mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar drwxr-xr-x. 2 root root 4096 Apr 14 09:15 mysqlrpm -rw-r--r--. 1 root root 20 Apr 15 11:08 shellTest2.sh -rw-r--r--. 1 root root 186 Apr 15 11:05 shellTest.sh 3318 [root@hadoop001 scripts]# ll /opt/script/ ; sh shellTest2.sh ls: cannot access /opt/script/: No such file or directory 3320
-a:逻辑与,cmd1 -a cmd2,cmd1和cmd2都为真时才为真
[root@hadoop001 scripts]# [ -e /opt/scripts/ -a 2 -eq 2 ];echo $? 0 [root@hadoop001 scripts]# [ -e /opt/script/ -a 2 -eq 2 ];echo $? 1
-o:逻辑或,cmd1 -o cmd2,cmd1和cmd2都为假时才为假
[root@hadoop001 scripts]# [ -e /opt/scripts/ -o 2 -eq 2 ];echo $? 0 [root@hadoop001 scripts]# [ -e /opt/script/ -o 2 -eq 3 ];echo $? 1
! :逻辑非,! cmd,注意在[]里面
[root@hadoop001 scripts]# [ -e /opt/scripts/ ];echo $? 0 [root@hadoop001 scripts]# [ ! -e /opt/scripts/ ];echo $? 1
date 获取以及零时修改当前时间:
[root@hadoop001 ~]# date Wed Apr 10 02:20:57 CST 2019 [root@hadoop001 ~]# date -s "2019-04-10 02:20:57" Wed Apr 10 02:20:57 CST 2019 [root@hadoop001 ~]# date -s "2019-04-10 13:54:00"
命令帮助查看:
[hadoop@hadoop001 ~]$man date [hadoop@hadoop001 ~]$man help
时间格式化输出:
[hadoop@hadoop001 ~]$ date Wed Apr 10 14:32:36 CST 2019 [hadoop@hadoop001 ~]$ date '+%Y%m%d%H%M%S' 20190410143424 [hadoop@hadoop001 ~]$ date "+%Y%m%d%H%M%S" 20190410143446
用例:
[root@hadoop001 scripts]# sh shellTest3.sh [root@hadoop001 scripts]# ll total 584516 -rw-r--r--. 1 root root 0 Apr 15 11:40 20190415114052.log -rw-r--r--. 1 root root 598528000 Jan 1 06:01 mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar drwxr-xr-x. 2 root root 4096 Apr 14 09:15 mysqlrpm -rw-r--r--. 1 root root 20 Apr 15 11:08 shellTest2.sh -rw-r--r--. 1 root root 47 Apr 15 11:40 shellTest3.sh -rw-r--r--. 1 root root 186 Apr 15 11:05 shellTest.sh [root@hadoop001 scripts]# cat shellTest3.sh #!/bin/bash touch $(date "+%Y%m%d%H%M%S").log
字符串截取:
[hadoop@hadoop001 ~]$ a="123456" [hadoop@hadoop001 ~]$ echo ${a:2:3} 345
取前缀:
[hadoop@hadoop001 ~]$ a="123.log" [hadoop@hadoop001 ~]$ echo ${a%.*} 123
结构:
变量名=(元素1 元素2 元素3 元素4 元素5 元素6 )
#注意 默认元素间是以空格分隔用列:
#用列1,元素间使用空格分隔,循环数组 [root@hadoop001 wsktest]# cat array.sh #!/bin/bash arr=(ruoze jepson xingxing wsk shiqi) for i in ${arr[@]} do echo $i done [root@hadoop001 wsktest]# sh array.sh ruoze jepson xingxing wsk shiqi #用列2,字符串间使用逗分隔,OLD_IFS,IFS这些事固定写法,分隔字符串。 [root@hadoop001 wsktest]# cat array.sh #!/bin/bash S="ruoze,jepson,xingxing,wsk,shiqi" OLD_IFS="$IFS" IFS="," arr=($S) IFS="OLD_IFS" for i in ${arr[@]} do echo $i done [root@hadoop001 wsktest]# sh array.sh ruoze jepson xingxing wsk shiqi
语法:
#语法1:
for 变量 in 集合
do
逻辑
done
#语法2
for((初始变脸;结束循环调节;变量))
do
逻辑
done用例:
[root@hadoop001 wsktest]# cat wskshell5.sh #!/bin/bash for i in tony jet bob do echo $i echo "hello $i" done [root@hadoop001 wsktest]# sh wskshell5.sh tony hello tony jet hello jet bob hello bob #用例2,注意{1..10}可以用`seq 10`取代 [root@hadoop001 wsktest]# cat wskshell6.sh #!/bin/bash for i in {1..10} do mkdir dir$i done [root@hadoop001 wsktest]# sh wskshell6.sh [root@hadoop001 wsktest]# ll total 64 -rw-r--r--. 1 root root 0 Apr 10 14:41 20190410144112.log drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir1 drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir10 drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir2 drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir3 drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir4 drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir5 drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir6 drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir7 drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir8 drwxr-xr-x. 2 root root 4096 Apr 10 15:50 dir9 #用例3 [root@hadoop001 wsktest]# cat wskshell7.sh #!/bin/bash for((i=1;i<10;i++)) do sum=$((sum+$i)) done echo $sum [root@hadoop001 wsktest]# sh wskshell7.sh 45
语法:
#语法1
while [条件]
do
逻辑
done
#语法2
while read -r line
do
逻辑
done用例:
用例1,注意 变量=变量值 ,若写成$变量=变量值就错了,$变量就是变量值的意思 [root@hadoop001 wsktest]# cat wskshell8.sh #!/bin/bash i=0 sum=0 while [ $i -lt 10 ] do sum=$(($sum+$i)) i=$[$i+1] done echo $sum #用例2,读取文件的每一行 [root@hadoop001 wsktest]# cat wskshell9.sh #!/bin/bash while read -r line do echo $line done <shellTest.sh [root@hadoop001 wsktest]# sh wskshell9.sh #!/bin/bash test(){ echo "未添加引号" echo $* echo $@ echo "添加了引号" for N in $* do echo $N done echo "----------------" for N in $@ do echo $N done } test 1 2 3 4 5 6 #用例4,读取文件的每一行,并取第一列和hello拼接 [root@hadoop001 wsktest]# cat wskshell10.sh #!/bin/bash while read -r line do echo `echo $line | awk -F: '{print $1}'`:hello done < /etc/passwd [root@hadoop001 wsktest]# sh wskshell10.sh root:hello bin:hello daemon:hello adm:hello lp:hello sync:hello shutdown:hello
语法:
#语法1
if 条件
then
逻辑
fi
#语法2
if 条件
then
逻辑
else
逻辑
fi
#语法3
if 条件
then
逻辑
elif
then
逻辑
else
逻辑
fi用例:
# 用列1 [root@hadoop001 wsktest]# cat wskshell11.sh #!/bin/bash if [ 2 -eq 2 ] then echo yes else echo no fi [root@hadoop001 wsktest]# sh wskshell11.sh yes #用列2 [root@hadoop001 wsktest]# sh wskshell20.sh -1 参数小于0 [root@hadoop001 wsktest]# sh wskshell20.sh 5 参数小于10 [root@hadoop001 wsktest]# sh wskshell20.sh 15 参数小于20 [root@hadoop001 wsktest]# sh wskshell20.sh 24 参数大于等于20
语法:
语法1:
case $变量名称 in
条件1)
命令序列
;;
条件2)
命令序列
;;
条件3)
命令序列
;;
*)
esac
语法2:
case $变量名称 in
条件1|条件2)
命令序列
;;
条件3|条件4)
命令序列
;;
条件5|条件6)
命令序列
;;
*)
esac用例:
[root@hadoop001 wsktest]# cat wskshell12.sh #!/bin/bash case $1 in 1) echo "我是"$1 ;; 2) echo "我是"$1 ;; 3) echo "我是"$1 ;; *) echo "我是"$1 ;; esac [root@hadoop001 wsktest]# sh wskshell12.sh 2 我是2
语法:
语法1:
name(){
命令序列
}
语法2:
function name{
命令序列
}用例:
[root@hadoop001 wsktest]# cat wskshell13.sh #!/bin/bash sum(){ echo $(($1+$2)) } sum 2 5 [root@hadoop001 wsktest]# sh wskshell13.sh 7
注意:
1)shell是顺序执行的,故函数体要写在函数调用前
2)函数的参数的传递通过$1…9
语法:
awk ‘{pattern + action}’ {filenames}
用例:
[root@hadoop001 wsktest]# cat test.log a,1,你 b,2,们 c,3,好 d,4,啊 e,5,我 #输出第一行,NR表示行号 [root@hadoop001 wsktest]# cat test.log| awk -F "," 'NR==1' a,1,你 #输出第一行之后的所有行 [root@hadoop001 wsktest]# cat test.log| awk -F "," 'NR>1' b,2,们 c,3,好 d,4,啊 e,5,我 #输出第一列和第二列 [root@hadoop001 wsktest]# awk -F "," '{print $1,$2}' test.log a 1 b 2 c 3 d 4 e 5 #输出第2列第二行 [root@hadoop001 wsktest]# awk -F "," 'NR==2{print $2}' test.log 2
语法:
sed [options] ‘command’ file(s)
用例:
#将文件里的每行首个a使用aa替换 [root@hadoop001 wsktest]# cat sed.log a ser swef 123 43 45 44 5 a 1333 hello [root@hadoop001 wsktest]# sed -i 's/a/aa/' sed.log [root@hadoop001 wsktest]# cat sed.log aa ser swef 123 43 45 44 5 aa 1333 hello #将文件中的每行首个aa使用b'替换 [root@hadoop001 wsktest]# cat sed.log aa ser swef 123 43 45 44 5 aa 1333 hello [root@hadoop001 wsktest]# sed -i "s/aa/b'/" sed.log [root@hadoop001 wsktest]# cat sed.log b' ser swef 123 43 45 44 5 b' 1333 hello #将文件中的s使用ll全局替换 [root@hadoop001 wsktest]# cat sed.log sss ser swef 123 43 45 44 5 sss 1333 hello [root@hadoop001 wsktest]# sed -i "s/s/ll/g" sed.log [root@hadoop001 wsktest]# cat sed.log llllll ller llwef 123 43 45 44 5 llllll 1333 hello #将文件的每行首添加指定字符串 [root@hadoop001 wsktest]# cat sed.log llllll ller llwef 123 43 45 44 5 llllll 1333 hello [root@hadoop001 wsktest]# sed -i 's/^/uu&/g' sed.log [root@hadoop001 wsktest]# cat sed.log uullllll ller llwef uu123 43 45 uu44 5 llllll 1333 uuhello #将文件的每行尾添加指定字符串 [root@hadoop001 wsktest]# sed -i 's/$/&wwk/g' sed.log [root@hadoop001 wsktest]# cat sed.log uullllll ller llwefwwk uu123 43 45 wwk uu44 5 llllll 1333wwk uuhellowwk
语法:
#生产用的最多
确保服务是启动,service crond status
确保服务是开机自启动的,chkconfig crond --list;确保在系统对应的启动级别上(主要是3和5)该服务是on的,即开机自启动
crontal -l 列出所有的计划任务
crontab -e 进入计划任务编辑,注意* * * * * ,代表每分、时、日、月、周
用例:
#上方的计划任务表示每周3的夜里两点执行 任务 [root@hadoop001 wsktest]# crontab -l 0 2 * * 3 cp /etc/passwd /tmp #每隔半个月清空/tmp临时文件 [root@hadoop001 wsktest]# crontab -l 0 1 10,25 * * rm -rf /tmp/* #每隔10小时进行时间同步 [root@hadoop001 wsktest]# crontab -l 0 */10 * * * ntpdate 0.asia.pool.ntp.org #每天夜里1,2,3,4,5,6点执行时钟同步 [root@hadoop001 wsktest]# crontab -l 0 1-6 * * * ntpdate 0.asia.pool.ntp.org
1:/etc/init.d/目录下都是系统启动脚本
2:cat /etc/shells ,可查询系统的shell环境有哪些
3:shell中单引号(’’)与双引号("")都是用来表示字符串,唯一区别时双引号会解释字符串中的特殊字符($ `)而单引号不会; \ 表示命令换行
4:反引号括起来的是一行命令(``),是用于将一个命令的标准输出插在一个命令行中任何位置等价于$(cmd),kill -9 $(pgrep xx),查询某进程并杀死。