命令功能
通过crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令非常适合周期性的日志分析或数据备份等工作。
## 查看crontab服务状态:service crond status
crontab -l [-u user] ## 列出用户目前的crontab.
crontab -e [-u user] ## 编辑用户目前的crontab.
在crontab -e 里加入一些要执行的命令 ,比如说*/1 * * * * echo “haha” >> /root/haha.txt 意思是每分钟往haha.txt文件追加一次haha
在crontab -e 里写完了 保存即可,不需要执行。用tail -F haha.txt动态监视即可
调度配置
1,配置说明
基本格式:
* * * * * command
分 时 日 月 周 命令
第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时0~23(0表示0点) 7-9表示:7点到9点之间
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
2,配置示例
*/1 * * * * date >> /root/date.txt
上面的例子表示每分钟执行一次date命令
30 21 * * * /usr/local/etc/rc.d/httpd restart
上面的例子表示每晚的21:30重启apache。
45 4 1,10,22 * * /usr/local/etc/rc.d/httpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。
10 1 * * 6,0 /usr/local/etc/rc.d/httpd restart
上面的例子表示每周六、周日的1 : 10重启apache。
0,30 18-23 * * * /usr/local/etc/rc.d/httpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。
0 23 * * 6 /usr/local/etc/rc.d/httpd restart
上面的例子表示每星期六的11 : 00 pm重启apache。
- */1 * * * /usr/local/etc/rc.d/httpd restart
上面的例子每一小时重启apache - 23-7/1 * * * /usr/local/etc/rc.d/httpd restart
上面的例子晚上11点到早上7点之间,每隔一小时重启apache
0 11 4 * mon-wed /usr/local/etc/rc.d/httpd restart
上面的例子每月的4号与每周一到周三的11点重启apache
0 4 1 jan * /usr/local/etc/rc.d/httpd restart
上面的例子一月一号的4点重启apache
shell编程
1基本格式
在文件中,通常以.sh为后缀的是shell脚本
编辑命令:vi hello.sh
在编辑时第一行必须写#1/bin/bash
执行脚本命令:sh hello.sh或者 在当前目录下./hello.sh(必须是可执行的文件即 -rwxr-xr-x )
一个练习
[root@Tyler01 lianxi]# vi hello.sh
[root@Tyler01 lianxi]# sh hello.sh
hello word
[root@Tyler01 lianxi]# ./hello.sh
-bash: ./hello.sh: 权限不够
[root@Tyler01 lianxi]# chmod 755 hello.sh
[root@Tyler01 lianxi]# ll
总用量 8
-rw-r–r-- 1 root root 0 8月 27 15:19 a.txt
-rw-r–r-- 1 root root 0 8月 27 15:20 date.txt
-rw-r–r-- 1 root root 36 8月 27 15:07 haha.txt
-rwxr-xr-x 1 root root 77 8月 27 15:31 hello.sh
[root@Tyler01 lianxi]# ./hello.sh
hello word
2,基本语法
2.1系统变量
通过set命令执行系统变量
2.2用户变量
用户自己定义的变量也会在set中
[root@Tyler01 lianxi]#a=hello world
-bash: world: command not found
多了一个空格,world命令不存在
在变量a的输出hello world后边+s
[root@Tyler01 lianxi]# echo $a+“s”
hello world+s
[root@Tyler01 lianxi]# echo $a"s"
hello worlds
[root@Tyler01 lianxi]# echo $as
或者
[root@Tyler01 lianxi]# echo ${a}s
hello worlds
2.3变量注意
变量=值 (例如STR=abc)
等号两侧不能有空格
2.4示例
STR=“hello world”
A=9
echo $A
echo $STR
如果想打印 hello worlds is greater 怎么办?
echo $STRs is greate 行吗?
不行,正确写法是:
echo ${STR}s is greate
2.5示列2
在变量a的输出hello world后边+s
[root@hdp01 ~]# echo $a+“s”
hello world+s
[root@hdp01 ~]# echo $a"s"
hello worlds
[root@hdp01 ~]# echo $as
或者
[root@hdp01 ~]# echo ${a}s
hello worlds
注意 这里定义的变量需要自己去撤销 unset 变量名
2.6 export
可把变量提升为当前shell进程中的全局环境变量,可供其他shell程序使用
看个练习
注意注意注意 重要的事情说三遍 在这执行的时候如果报错 “权限不够” 说明文件没有可执行权限
改变权限 [root@Tyler01 lianxi]# chmod 755 a.sh 即可
[root@Tyler01 lianxi]# vi a.sh
#!/bin/bash
a=“a in a.sh”
echo $a
[root@Tyler01 lianxi]# sh a.sh
a in a.sh
[root@Tyler01 lianxi]# vi b.sh
#!/bin/bash
b=“b in b.sh”
echo $b
[root@Tyler01 lianxi]# sh b.sh
b in b.txt
[root@Tyler01 lianxi]# vi a.sh
#!/bin/bash
export a=“a in a.sh”
echo $a
/aaa/lianxi/b.sh #也可写成. ./b.sh 或者 source ./b.sh(这里第一个 . 和source 是将进程向前扩大了一级)
[root@Tyler01 lianxi]# vi b.sh
#!/bin/bash
export b=“b in b.sh”
echo $b
echo $a
[root@Tyler01 lianxi]# sh b.sh
b in b.txt
[root@Tyler01 lianxi]# sh a.sh
a in a.sh
b in b.txt
a in a.sh
总结:
1、a.sh中直接调用b.sh,会让b.sh在a所在的bash进程的“子进程”空间中执行
2、而子进程空间只能访问父进程中用export定义的变量
3、一个shell进程无法将自己定义的变量提升到父进程空间中去
4、“.”号执行.sh脚本时,会让脚本在调用者所在的shell进程空间中执行
2.7反引号赋值
[root@Tyler01 lianxi]# a=ls -a
# 反引号,运行里面的命令,并把结果返回给变量a
[root@Tyler01 lianxi]# a a=$(ls -la) ## 等价于反引号
-bash: a: command not found
[root@Tyler01 lianxi]# echo $a
. … a.sh a.txt b.sh date.txt haha.txt hello.sh
[root@Tyler01 lianxi]# a=$(ls -a)
[root@Tyler01 lianxi]# echo $a
. … a.sh a.txt b.sh date.txt haha.txt hello.sh
[root@Tyler01 lianxi]#
2.8特殊变量
$? 表示上一个命令退出的状态码(0-255)
$$ 表示当前进程编号
$0 表示当前脚本名称
$n 表示n位置的输入参数(n代表数字,n>=1)
$# 表示参数的个数,常用于循环
∗
和
*和
∗和@ 都表示参数列表
注意两者区别
$* 和 $@ 都以$1 $2 …
n
的
形
式
组
成
参
数
列
表
当
它
们
被
双
引
号
"
"
包
含
时
—
—
"
n 的形式组成参数列表 当它们被双引号" "包含时—— "
n的形式组成参数列表当它们被双引号""包含时——"*" 会将所有的参数作为一个整体,以"$1 $2 …
n
"
的
形
式
组
成
一
个
整
串
;
"
n"的形式组成一个整串; "
n"的形式组成一个整串;"@" 会将各个参数分开,以"$1" “
2
"
…
"
2" … "
2"…"n” 的形式组成一个参数列表
例子
[root@Tyler01 lianxi]# vi canshu.sh
#!/bin/bash
echo $$
echo $?
echo $1
echo $2
echo $3
echo $*
echo $@
echo $#
echo $o
[root@Tyler01 lianxi]# sh canshu.sh
18827
0
0
[root@Tyler01 lianxi]# ./canshu.sh
-bash: ./canshu.sh: 权限不够
[root@Tyler01 lianxi]# chmod 755 canshu.sh
[root@Tyler01 lianxi]# ./canshu.sh
18862
0
0
[root@Tyler01 lianxi]# ll
总用量 20
-rwxr-xr-x 1 root root 51 8月 27 16:31 a.sh
-rw-r–r-- 1 root root 0 8月 27 15:19 a.txt
-rwxr-xr-x 1 root root 44 8月 27 16:05 b.sh
-rwxr-xr-x 1 root root 84 8月 27 17:00 canshu.sh
-rw-r–r-- 1 root root 0 8月 27 15:20 date.txt
-rw-r–r-- 1 root root 36 8月 27 15:07 haha.txt
-rwxr-xr-x 1 root root 77 8月 27 15:31 hello.sh
[root@Tyler01 lianxi]# sh canshu.sh c v d
18868
0
c
v
d
c v d
c v d
3
2.9算数表达式运算
2.9.1用 expr
格式 expr m + n 或$((m+n)) 注意expr运算符间要有空格
[root@Tyler01 lianxi]# a=expr 2 + 3
[root@Tyler01 lianxi]# echo KaTeX parse error: Expected 'EOF', got '#' at position 26: …Tyler01 lianxi]#̲ b=((2+3))
[root@Tyler01 lianxi]# echo $b
5
[root@Tyler01 lianxi]# c=expr $b \* 4
#乘法 * 号需要转义
[root@Tyler01 lianxi]# echo $c
20
2.9.2用(())
[root@Tyler01 lianxi]# a=$((1+2))
[root@Tyler01 lianxi]# echo $a
3
[root@Tyler01 lianxi]# echo $((2+3)*4)
-bash: command substitution: line 1: syntax error near unexpected token *4' -bash: command substitution: line 1:
(2+3)*4’
[root@Tyler01 lianxi]# echo KaTeX parse error: Expected 'EOF', got '#' at position 19: …2+3)*4)) #̲多加一个运算就多加一对() 2…[ ] (与(())相似)*
[root@Tyler01 lianxi]# a=$[1+2]
[root@Tyler01 lianxi]# echo $a
3
2.9.4 用let
[root@Tyler01 lianxi]# i=1
[root@Tyler01 lianxi]# let i++
[root@Tyler01 lianxi]# echo $i
2
[root@Tyler01 lianxi]# echo $i
2
[root@Tyler01 lianxi]# let i++ #这句每次都要执行 才会加加
[root@Tyler01 lianxi]# echo $i
3
2.10流程控制
if条件语句
[root@Tyler01 aaa]# cat a.sh
#!/bin/bash
read -p “please input your name:” name
if [ $name = root ] # 这里注意 [ ] 两边必须要空格 =号两边也必须有空格,
#=号左右没有空格 $NAME=root默认是输入一个参数,只要这个参数(不包括什么也不输入会报错),就永远都是true,条件永远成立
then
echo “hello ${name},welcome” #这里" “空格有没有都可以
elif [
n
a
m
e
=
t
y
l
e
r
1
]
t
h
e
n
e
c
h
o
"
h
e
l
l
o
name = tyler1 ] then echo "hello
name=tyler1]thenecho"hello{name},welcome”
else
echo “sb,get out here”
fi
[root@Tyler01 aaa]# sh a.sh
please input your name:root
hello root,welcome
[root@Tyler01 aaa]# sh a.sh
please input your name:tyler
sb,get out here
[root@Tyler01 aaa]# sh a.sh
please input your name:tyler1
hellotyler1,welcome
判断条件
1/ 条件判断基本语法
[ condition ] (注意condition前后要有空格)
#非空返回true
[ edu360 ]
#空返回false
[ ]
用例子好明白
[root@Tyler01 aaa]# if [ a = b ];then echo ok;else echo notok;fi
notok
[root@Tyler01 aaa]# if [ a = a ];then echo ok;else echo notok;fi
ok
短路(理解为三元运算符)
条件满足,执行&&后面的语句;条件不满足,执行|| 后面的语句
例子
[root@Tyler01 aaa]# [ a = b ] && echo OK || echo notok
notok
[root@Tyler01 aaa]# [ a = a ] && echo OK || echo notok
OK
2/ 条件判断组合
注:[] 与[[ ]] 的区别:[[ ]] 中逻辑组合可以使用 && || 符号
而[] 里面逻辑组合可以用 -a -o 其中-a是and;-o是or
[root@Tyler01 aaa]# if [ a = b && b = c ];then echo ok;else echo ko;fi
-bash: [: missing `]’
ko
[root@Tyler01 aaa]# if [ a = b -a b = b ];then echo ok;else echo ko;fi
ko
[root@Tyler01 aaa]# if [ a = b -o b = b ];then echo ok;else echo ko;fi
ok
[root@Tyler01 aaa]# if [[ a = b -o b = b ]];then echo ok;else echo ko;fi #[[ ]] 就点用&&和 || 不能用-a,-o了
-bash: syntax error in conditional expression
-bash: syntax error near `-o’
[root@Tyler01 aaa]# if [[ a = b && b = b ]];then echo ok;else echo ko;fi
ko
[root@Tyler01 aaa]# if [[ a = b || b = b ]];then echo ok;else echo ko;fi
ok
3/ 常用判断运算符
字符串比较:
= 字符串是否相等
!= 字符串是否不相等
-z 字符串长度为0返回true
-n 字符串长度不为0返回true
if [ ‘aa’ = ‘bb’ ]; then echo ok; else echo notok;fi
if [ -n “aa” ]; then echo ok; else echo notok;fi
if [ -z “” ]; then echo ok; else echo notok;fi
整数比较:
-lt 小于
-le 小于等于
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于
还可以用转义的数学符号 <
文件判断:
-d 是否为目录
if [ -d /bin ]; then echo ok; else echo notok;fi
-f 是否为文件
if [ -f /bin/ls ]; then echo ok; else echo notok;fi
-e 是否存在
if [ -e /bin/ls ]; then echo ok; else echo notok;fi
4 case语法(用的多)
case $1 in
start)
echo “starting”
;;
stop)
echo “stoping”
;;
*)
echo “Usage: {start|stop}”
esac
5 for语法
第一种
for N in 1 2 a
do
echo $N
done
或
for N in 1 2 3; do echo $N; done
或
for N in {1…3}; do echo $N; done
第二种
for ((i = 0; i <= 5; i++))
do
echo “welcome $i times”
done
或
for ((i = 0; i <= 5; i++)); do echo “welcome $i times”; done
2.11 函数使用
用个例子来了解函数定义
[root@Tyler01 lianxi]# cat hanshu.sh
#!/bin/bash
fun(){ # 函数定义
echo "Hello there today's date is `date +%Y-%m-%d`"
return 2 #返回值其实是状态码,只能在[0-255]范围内
}
echo “now going to the fun hello”
fun #调用函数
echo KaTeX parse error: Expected 'EOF', got '#' at position 13: ? #̲获取函数的return值(即:…? 系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
函数参数
[root@Tyler01 lianxi]# vi hanshucanshu.sh
#!/bin/bash
fun1.sh
fun(){
echo “第一个参数为 $1 !”
echo “第二个参数为 $2 !”
echo “第十个参数为 $10 !” #$10 $1是第一个参数的值 在连接上个0
echo “第十个参数为 ${10} !”
echo “第十一个参数为 ${11} !”
echo “参数总数有 $# 个!”
echo “作为一个字符串输出所有参数 $* !”
}
fun 121 2 3 4 5 6 7 8 9 34 73
[root@Tyler01 lianxi]# sh hanshucanshu.sh
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !
[root@Tyler01 lianxi]# vi hanshucanshu.sh
[root@Tyler01 lianxi]# sh hanshucanshu.sh
第一个参数为 121 !
第二个参数为 2 !
第十个参数为 1210 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 121 2 3 4 5 6 7 8 9 34 73 !
函数返回值
[root@Tyler01 lianxi]# vi fun1.sh
#!/bin/bash
#fun1.sh
fun(){
echo “这个函数会对输入的两个数字进行相加运算…”
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo “两个数字分别为 $aNum 和 $anotherNum !”
return
(
(
((
((aNum+$anotherNum))
}
fun
echo “输入的两个数字之和为 $? !”
[root@Tyler01 lianxi]# sh fun1.sh
这个函数会对输入的两个数字进行相加运算…
输入第一个数字:
4
输入第二个数字:
5
两个数字分别为 4 和 5 !
输入的两个数字之和为 9 !
2.12 expect 的使用
使用scp命令远程拷贝文件时,会有人机交互的过程,如何让脚本完成人机交互?
妙药: expect
用法示例:
先观察 ssh localhost 的过程
再看expect的功能
#!/bin/bash/expect
exp_test.sh
set timeout -1;
spawn ssh localhost;
expect {
“(yes/no)” {send “yes\r”;exp_continue;}
“password:” {send “hadoop\r”;exp_continue;}
eof {exit 0;}
}
执行: expect -f exp_test.sh
收货满满的一天!!!不写不知道一些吓一跳,没想到会写这么多!!! refuel !!!