1)shell文件行业规范默认后缀为.sh
2)shell首行为#!/bin/bash,注意/bin/bash为当前脚本解释器,可以不写但不能写错了。
3)#表示注释
4)shell对大小写敏感,变量尽量全大写,小写会被鄙视
全局生效
通过set命令查看
用户环境变量,当前用户生效
系统环境变量,所有用户生效
通过export声明变量
将脚本的参数传给脚本,多个参数使用空格隔开
$0:脚本文件名称
$1、$2....$9 :执行脚本的参数
#用例
[root@hadoop001 wsktest]# cat shellTest.sh
#!/bin/bash
echo "$0"
echo "$2"
echo "$3"
echo "$1"
[root@hadoop001 wsktest]# sh shellTest.sh start
shellTest.sh
start
$0:代表当前脚本的名称
$!:后台运行的最后一个进程的PID
$?:上一个命令退出的状态(0:成功,非0:失败)
$*:当前shell参数集合(整体)
$$:表示当前进程ID号码
$#:代表当前shell的参数个数
$@:当前shell参数集合(逐个读取)
[root@hadoop001 wsktest]# ll
total 4
-rw-r--r--. 1 root root 55 Apr 9 17:15 shellTest.sh
[root@hadoop001 wsktest]# echo $?
0
[root@hadoop001 wsktest]# lll
-bash: lll: command not found
[root@hadoop001 wsktest]# echo $?
127
[root@hadoop001 wsktest]# cat shellTest.sh
#!/bin/bash
echo "$#"
[root@hadoop001 wsktest]# sh shellTest.sh start stop restart
3
[root@hadoop001 wsktest]#
[root@hadoop001 wsktest]# cat shellTest.sh
#!/bin/bash
echo "$*"
[root@hadoop001 wsktest]# sh shellTest.sh start stop restart
start stop restart
[root@hadoop001 wsktest]# 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 wsktest]# 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
[root@hadoop001 wsktest]#
[root@hadoop001 wsktest]# cat wskshell2.sh
#!/bin/bash
echo $$
[root@hadoop001 wsktest]# sh wskshell2.sh
30772
[root@hadoop001 wsktest]# sh wskshell2.sh
30773
[root@hadoop001 wsktest]# sh wskshell2.sh
30774
1)shell文件默认是无执行权限,编辑完成可添加执行权限:chmod +x shellFile,或 sh shellFile 或 bash shellFile 或 source shellFile 或. shellFile来执行脚本
变量名=变量值
注意:
1、等号两边不能有空格
2、变量名大小写敏感,官方建议大写
变量取值:$变量名 或${变量名}
[root@hadoop001 wsktest]# storn=3
[root@hadoop001 wsktest]# echo ${storn}
3
运算符:+ - * / %
$((expression)) 或
$[expression] 或
expr expression
[root@hadoop001 wsktest]# echo $((5+4))
9
[root@hadoop001 wsktest]# echo $[5+4]
9
[root@hadoop001 wsktest]# expr 5+4
expr 5+4
[root@hadoop001 wsktest]# expr 5 + 4
9
注意:expr运算的变量间有无空格差别很大
test 测试表达式 或
[ 测试表达式 ]
[root@hadoop001 wsktest]# [ $a -lt $b ]
[root@hadoop001 wsktest]# echo $?
1
[root@hadoop001 wsktest]# [ $a -ge $b ]
[root@hadoop001 wsktest]# echo $?
0
1、测试表达式与[]之前必须有空格
-eq 等于,equal
-ne 不等于,not equal
-gt 大于,greate than
-ge 大于等于,greate than or equal
-lt 小于,less than
-le 小于等于,less than or equal
[root@hadoop001 wsktest]# [ $a -lt $b ]
[root@hadoop001 wsktest]# echo $?
1
[root@hadoop001 wsktest]# [ $a -ge $b ]
[root@hadoop001 wsktest]# echo $?
0
= 等于
!= 不等于
-z 长度为零,如: [ -z "$myvar" ]
-n 度为零,如: [ -z "$myvar" ]
[root@hadoop001 ~]# a="he"
[root@hadoop001 ~]# b="ha"
[root@hadoop001 ~]# c="he"
[root@hadoop001 ~]# [ a = b ] ;echo $?
1
[root@hadoop001 ~]# [ a = c ] ;echo $?
1
[root@hadoop001 ~]# [ $a = $b ] ;echo $?
1
[root@hadoop001 ~]# [ $a = $c ] ;echo $?
0
[root@hadoop001 ~]# [ $a == $c ] ;echo $?
0
[root@hadoop001 ~]# [ $a == $b ] ;echo $?
1
[root@hadoop001 ~]# [ "$a" == "$b" ];echo $?
1
[root@hadoop001 ~]# [ "$a" == "$c" ];echo $?
0
[root@hadoop001 wsktest]# [ -z "$a" ]
[root@hadoop001 wsktest]# echo $?
1
[root@hadoop001 wsktest]# [ -z "" ]
[root@hadoop001 wsktest]# echo $?
0
1、字符串比较时可以用=也可以用==,左右离比较符必须有空格
2、等于“=”不仅可以用来比较字符串也可以比较数字,注意要有空格,否则就是赋值了。
-e 文件名,文件存在为真
-r 文件名,文件存在且可读为真
-w 文件名,文件存在且可写为真
-x 文件名,文件存在且可执行为真
-s 文件名,文件存在且有一个字符为真
-d 文件名,文件存在且为目录为真,目录ll显示为d
-f 文件名,文件存在且为普通文件为真,普通文件类型为-
-c 文件名,文件存在且为字符串型特殊文件为真,几乎不用使用到。ll /dev/ 可查看c类型文件
-b 文件名,文件存在且为块特殊文件为真,几乎不会使用到。ll /dev/ 可查看b类型文件
[root@hadoop001 wsktest]# [ -f shellTest.sh ]
[root@hadoop001 wsktest]# echo $?
0
[root@hadoop001 wsktest]# [ -d shellTest.sh ]
[root@hadoop001 wsktest]# echo $?
1
代表命令行之间的关系
&&:命令与,
||:命令或
; :命令先后关系
-a:逻辑与
-o:逻辑或
! :逻辑非
[root@hadoop001 wsktest]# cat wskshell2.sh
#!/bin/bash
echo $$
[root@hadoop001 wsktest]# ll /pwd/ssssss && sh wskshell2.sh
ls: cannot access /pwd/ssssss: No such file or directory
[root@hadoop001 wsktest]# ll /etc/passwd && sh wskshell2.sh
-rw-r--r--. 1 root root 1664 Apr 7 11:32 /etc/passwd
33536
[root@hadoop001 wsktest]# ll /pwd/ssssss || sh wskshell2.sh
ls: cannot access /pwd/ssssss: No such file or directory
33551
[root@hadoop001 wsktest]# ll /etc/passwd || sh wskshell2.sh
-rw-r--r--. 1 root root 1664 Apr 7 11:32 /etc/passwd
[root@hadoop001 wsktest]#
[root@hadoop001 wsktest]# ll /etc/passwd ; sh wskshell2.sh
-rw-r--r--. 1 root root 1664 Apr 7 11:32 /etc/passwd
33566
[root@hadoop001 wsktest]# ll /pwd/ssssss ; sh wskshell2.sh
ls: cannot access /pwd/ssssss: No such file or directory
33568
[root@hadoop001 ~]# ll /root/wsktest/
total 8
-rw-r--r--. 1 root root 182 Apr 9 19:07 shellTest.sh
-rw-r--r--. 1 root root 21 Apr 9 19:10 wskshell2.sh
[root@hadoop001 ~]# [ -e /root/wsktest2 -a 2 -eq 2 ];echo $?
1
[root@hadoop001 ~]# [ -e /root/wsktest -a 2 -eq 2 ];echo $?
0
[root@hadoop001 ~]# [ -e /root/wsktest2 -o 2 -eq 2 ];echo $?
0
[root@hadoop001 ~]# [ -e /root/wsktest2 -o 2 -eq 3 ];echo $?
1
[root@hadoop001 ~]# [ ! -e /root/wsktest ];echo $?
1
[root@hadoop001 ~]# [ -e /root/wsktest ];echo $?
0
[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"
Wed Apr 10 13:54:00 CST 2019
[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
#创建当前时间戳.log文件
[root@hadoop001 wsktest]# cat wskshell4.sh
#!/bin/bash
touch $(date "+%Y%m%d%H%M%S").log
[root@hadoop001 wsktest]# sh wskshell4.sh
[root@hadoop001 wsktest]# ll
total 16
-rw-r--r--. 1 root root 0 Apr 10 14:41 20190410144112.log
-rw-r--r--. 1 root root 182 Apr 9 19:07 shellTest.sh
[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
#用例1
[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
#语法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
#生产不常用
#at 时间,设置一次性定时任务启动时间,并进入编辑模式
#ctr+d表示保存退出
#at -l 列出未执行的计划任务
[root@hadoop001 wsktest]# date
Thu Apr 11 02:08:47 CST 2019
[root@hadoop001 wsktest]# at 02:10
at> cp /etc/passwd /root/wsktest/
at>
job 4 at 2019-04-11 02:10
[root@hadoop001 wsktest]# ll /root/wsktest/
total 64
-rw-r--r--. 1 root root 0 Apr 10 14:41 20190410144112.log
-rw-r--r--. 1 root root 1664 Apr 11 02:10 passwd
#生产用的最多
# 确保服务是启动,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),查询某进程并杀死。