shell脚本学习
正则表达式
^开始标记
$结束标记
[a-z]
[A-Z]
[0-9]
. 单个任意字符
* 前面字符重复的次数>=0
+ 前面字符重复的次数>=1
? 前面字符重复的次数0 or 1
{n,m} 前面字符重复的次数n到m次
[A-Z][0-9][0-9] B12 B1A
# grep '^r.*n$' /etc/passwd
sed '匹配条件/执行的动作' /etc/passwd
或者
cat /etc/passwd | sed '匹配条件/执行的动作'
替换 sed 's/old/new/g'
ifconfig | grep 'inet addr:'
|grep -v '127.0.0.1'| sed 's/inet addr://g' | sed 's/Bcast.*//g'
awk
# awk -F: '{print $1}' /etc/passwd 取第一列,以冒号为分隔符
---------------------------------------------------------------------------------------
环境变量 系统 -- 多个用户set命令查看环境变量
--用户环境变量(/root/.bash_profile)
--系统环境变量(/etc/profile)
位置变量
--通常和脚本联合使用
--$0 脚本名称
--$1、$2、$3、$4…$9 位置参数
预定义变量
--$? 表示程序退出的代表(一般0代表执行成功,非0表示执行失败)
echo $?
--$# 代表当前shell的参数个数
--$*(一个整串) $@ (每个参数算一个字符串)代表所有参数
--$$ 当前进程的PID
自定义变量
--语法格式为:name=[value]
--注意:
变量等号两边不能有空格
变量对大小写敏感
--定义好后使用($变量名)来调用变量的值
算数运算
-- + - * / %
--$((expression))
--$[expression]
--expr expression
a=2(重复赋值会进行覆盖)
b=3
# echo $(($a+$b))或$(a+b)
# echo $[$a+$b]
# expr 5 + 2 注意有空格
# expr $a + $b
内置测试判断 成功/成立 -- 失败/不成立
--test 测试表达式
--[ 测试表达式 ] 最常见的
--注意: 测试表达式与中括号之间一定要有空格
数值比较
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真
举例1:
[root@localhost ~]# echo $a $b
2 3
[root@localhost ~]# test $a -lt $b
[root@localhost ~]# echo $?
0成功
[root@localhost ~]# test $a -gt $b
[root@localhost ~]# echo $?
1失败
举例2:
[root@localhost ~]# echo $a $b
2 3
[root@localhost ~]# [ $a -lt $b ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ $a -gt $b ]
[root@localhost ~]# echo $?
1
&& 逻辑与
-- cmd1 && cmd2 cmd1成功了才会执行cmd2
|| 逻辑或
-- cmd1 || cmd2 cmd1失败了才会执行cmd2
; 无逻辑关系
-- cmd1 ; cmd2 cmd1执行完后,执行cmd2
字串测试(字符串要用双引号引起来)
= 等于则为真
!= 不相等则为真
-z 字串 字串长度0则为真
-n 字串 字串长度不0则为真
文件测试
-e 文件名 如果文件存在则为真
-d 文件名 判断是否为目录
-f 文件名 如果文件存在且为普通文件则为真
-r 文件名 如果文件存在且可读则为真
-w 文件名 如果文件存在且可写则为真
-x 文件名 如果文件存在且可执行则为真
-s 文件名 如果文件存在且至少有一个字符则为真
Linux还提供了非(!)、或(-o)、与(-a)三个逻辑操作符,
用于将测试条件连接起来,其优先顺序为:!最高,-a次之,-o最低
date (man +命令,查看帮助)
# date '+%Y%m%d%H%M'
# date -d '7 day ago' '+%Y%m%d%H%M'
# date -s "2016-04-09 15:30:13" 修改系统时间(临时)
取字符串 ${变量名:offset:length}
[root@localhost ~]# a="201604091527"
[root@localhost ~]# echo $a
201604091527
[root@localhost ~]# echo ${a:2:3} 跳过两个取3个
160
取字符串 echo ${变量名%.*}
[root@localhost ~]# a="123.log"
[root@localhost ~]# echo ${a%.*}
123
find 查找文件
-type -name
-size(文件的大小) -mtime(文件的修改时间)
脚本案例:
#!/bin/bash
# #号表示注释
# shell脚本从上往下依次执行
date
grep 'root' /etc/passwd
执行脚本:
# chmod +x 1.sh
# /tmp/1.sh
. /tmp/1.sh 执行文件/tmp/1.sh
控制语句
#!/bin/bash
for i in {1..50}
do
mkdir /usr/local/src/dir$i
done
#!/bin/bash
for i in `seq 50` #反引号代表命令预先执行
do
mkdir /usr/local/src/dir$i
done
#!/bin/bash
for((i=1;i<=10;i++));do
SUM=$((SUM+i))
done
echo $SUM
#!/bin/bash
i=1
while [ $i -le 10 ]
do
SUM=$((SUM+i))
i=$[i+1]
done
echo $SUM
#!/bin/bash
while read -r line
do
echo $line:HELLO
done < /etc/passwd
username:hello
root: hello
adm: hello
#!/bin/bash
while read -r line
do
echo `echo $line | awk -F: '{print $1}'`:HELLO
done < /etc/passwd
#!/bin/bash
if [ -d /tmp/123 ];then
ls /tmp/123
else
mkdir /tmp/123
fi
top free
#!/bin/bash
case $1 in
top)
top
;;
free)
free
;;
df)
df
;;
*)
echo "usage:$0{top|free|df}"
esac
if for while case --控制语句
shell函数: 多次重复调用的一些命令通常可以放函数里面
#!/bin/bash
sum(){
echo $(($1+$2))
}
sum 5 6
计划任务
用法:at [时间] 指定时间执行特定命令
举例:
at 4:17 #指定在当天凌晨4点17分执行计划任务
at> cp /etc/passwd /tmp #计划任务内容
at> <EOT> #输入完成后,按ctrl+d结束 周期性的计划任务 crontab
1) service crond status
chkconfig --list | grep crond
crontab -e
0 2 * * 3 cp /etc/passwd /tmp每周三2点备份
5 1 10,25 * * rm -rf /tmp/* 每个月10号和25号凌晨1点5分清空
*/10 * * * * ntpdate 时间服务器IP 每10分钟执行时间同步
0 1-6 * * * 每天凌晨1点到6点执行
2)重启crond服务 service crond restart
tail -f动态查看
crontab [-u 用户] [-l|-r|-e]
-l:列出执行任务
-u:指定某个用户,不加-u选项则为当前用户
-e:制定计划任务