Tag: shell编程

Svn用户管理脚本

Posted by – 2009-09-15

一个工作需要重复5次以上,那就写个脚本吧.

一.删除一个svn用户
#—————————-引用文字-开始—————————-
#!/bin/bash
#Delect a svn user
#Author:楚霏
echo -n ” Please enter the user name whom you want to delete : ”
read NAME
#把下边这行的 “/home/svnroot/” 改为你的svn根目录
SVNROOT=/home/svnroot
#delect the name in authz
for i in `ls $SVNROOT/repository/`; do sed -i “s/$NAME\,//g” “$SVNROOT/repository/${i}/conf/authz”; done
for i in `ls $SVNROOT/repository/`; do sed -i “s/$NAME//g” “SVNROOT/repository/${i}/conf/authz”; done
#delcet the information in passwd
for i in `ls $SVNROOT/repository/`; do sed -i “/$NAME/d” “SVNROOT/repository/${i}/conf/passwd”; done
#check
grep -R $NAME $SVNROOT/repository/*/conf/*
#—————————-引用文字-结束—————————-

二.更改svn用户的密码
#—————————-引用文字-开始—————————-
#!/bin/bash
#Change a svn user’s passwd
#Author:楚霏
echo -n ” Please enter the username : ”
read NAME
echo -n “New password: ”
read PASSWD
#delect the name in authz
#把下边这行的 “/home/svnroot/” 改为你的svn根目录
SVNROOT=/home/svnroot
for i in `ls $SVNROOT/repository/`; do sed -i “s/^$NAME.*/$NAME = $PASSWD/g” “$SVNROOT/repository/${i}/conf/passwd”; done
echo “done”
#—————————-引用文字-结束—————————-

date命令详解与示例

Posted by – 2009-05-13


昨天需要写一个shell脚本,第一步是先获得昨天是几号。
然后我就写了近40行,又是判断月份,又是判断闰年,用了近两个小时。
猛的发现,date命令加一个参数就实现了
date +%d -d '-1 day'
苍天呀!这就是无知的代价!
索性又写篇博客介绍一下date命令

date用途:
用来显示或设定系统的日期与时间

使用方法:
date [参数] [+显示格式]

参数:
-d datestr : 显示 datestr 中所设定的时间 (非系统时间)
--help : 显示辅助讯息
-s datestr : 将系统时间设为 datestr 中所设定的时间
-u : 显示目前的格林威治时间
--version : 显示版本编号

显示格式:
方面,使用者可以设定欲显示的格式,格式设定为一个加号后接数个标记,其中可用的标记列表如下 :
###########################################
时间方面 :
%H : 小时,24小时制(00..23)
%k : 小时,24小时制(0..23)
%I : 小时,12小时制(01..12)
%l : 小时,12小时制(1..12)

%M : 分钟(00..59)

%s : 从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数
%S : 秒(00..61)

%p : 显示本地 AM 或 PM
%r : 直接显示时间 (12 小时制,格式为 hh:mm:ss [AP]M)
%T : 直接显示时间 (24 小时制,格式为 hh:mm:ss)
%X : 相当于 %H:%M:%S

%Z : 显示时区

日期方面 :
%a : 星期几,英文简写 (Sun..Sat)
%A : 星期几,英文全写 (Sunday..Saturday)

%b : 月份,英文简写 (Jan..Dec)
%B : 月份,英文全写 (January..December)
%m : 月份,显示为数字 (01..12)
%h : 月份,英文简写 (Jan..Dec),同%b

%c : 直接显示日期与时间
%d : 日 (01..31)
%D : 直接显示日期 (mm/dd/yy)

%w : 一周中的第几天 (0..6)
%j : 一年中的第几天 (001..366)
%U : 一年中的第几周 (00..53) (以 Sunday 为一周的第一天的情形)
%W : 一年中的第几周 (00..53) (以 Monday 为一周的第一天的情形)

%y : 年份的最后两位数字 (00.99)
%Y : 完整年份 (0000..9999)

%x : 直接显示日期 (mm/dd/yy)
###########################################
若是不以加号作为开头,则表示要设定时间,而时间格式为 MMDDhhmm[[CC]YY][.ss],其中 MM 为月份,DD 为日,hh 为小时,mm 为分钟,CC 为年份前两位数字,YY 为年份后两位数字,ss 为秒数
###########################################
示例:
#显示系统日期与时间
[root@bogon ~]# date
Wed May 13 09:29:47 CST 2009
#显示这是一年中的第几周
[root@bogon ~]# date +%W
19
#显示两年前今天的日期
[root@bogon ~]# date -d '-2 year'
Sun May 13 09:34:56 CST 2007
#也可以
[root@bogon ~]# date -d "2 year ago"
Sun May 13 09:37:12 CST 2007
#显示一年后今天是星期几
[root@bogon ~]# date -d '1 year' +%A
Thursday
#设置当前日期为2008-1-7,当前时间为12:34:56
[root@bogon ~]# date -s 01/07/2008
Mon Jan 7 00:00:00 CST 2008
[root@bogon ~]# date -s 12:34:56
Mon Jan 7 12:34:56 CST 2008

Chinaitlab 8cd linux教程笔记_SHELL编程部分

Posted by – 2009-02-27

############################
#Chinaitlab 8cd linux教程笔记_Shell编程部分#
############################

<1>shell简介
命令替换
myfile的内容
parm
findfile
#ls `cat myfile` -al
shell脚本基本元素
a.#!/bin/sh
b.#注释
c.变量 #用来存储信息
d.流程控制结构

管道| #一个命令输出作为后一个命令的输入
重定向<>#与管道相关,可以改变程序运行的输入来源和输出地点
sort <httpd.conf >httpd.conf.new
特殊字符
双引号:用来使shell无法认出空格、制表符和其它特殊字符
单引号:用来使shell无法认出所有特殊字符
反引号:用来替换命令
反斜杠:用来使shell无认出其后的特殊字符
分 号:允许在一行放多个命令
& :命令后台执行
括 号:创建成组的命令
大括号:创建命令块
竖 杠:管道
<>& :表示重定向
*?{}! :表示模式匹配
$ :变量名的开头
# :注释
空格 :当做空白
换行符:当做空白
制表符:当做空白
<2>shell变量和运算符
2.1.1本地变量
用户现在shell生命期的脚本中使用
veriable-name=value
set显示本地所有的变量
readonly variable-name
例:#LOCALTEST="test"
#echo ${LOCALTEST}
test
#readonly LOCALTEST
#LOCALTEST="test4"
bash:LOCALTEST:readonly variable
#readonly
declare -r LOCALTEST="test"
declare -ir UID="0"
2.1.2环境变量
环境变量用于所有用户的进程(通常称子进程)。
登录进程称父进程。shell执行的用户进程均称为子进程
环境变量可用于所有子进程,这包括编辑器、脚本和应用。
$HOME/.bash_profile(/etc/profile)
export来设置
env来查看
2.1.3变量替换
用变量的值替换它的名字
echo
在变量名前加$,使用echo命令可以显示单个变量取值
例:#testvar-"this is a test"
#echo ${testvar}
this is a test
变量替换(续)
${variable name} 显示实际值到variable name
${variable name:+value} 如果设置了variable name,显示值value,否则为空
${variable name:?value} 如果未设置variable name,显示自定义错误value
${variable name:-value} 如果未设置variable name,显示其值value
${variable name:=value} 如果未设置variable name,设置其值value,并显示
2.1.4变量清除
unset variable #readonly例外
2.1.5位置变量
位置变量表示$0,$1……$9
$0脚本名字
2.1.6标准shell变量
bash默认建立了一些标准环境变量,可在/etc/profile中定义
如:EXINIT
HOME
MAIL
MAILCHECK
MAILPATH
PATH #程序路径
PS1 #提示符
PS2 #一行运行多个命令时用
SHELL
TERMINFO
TERM
TZ #时区
PWD
LFS
LOGNAME
2.1.7特殊变量
$# 传递的到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数,不同于位置变量,此选项可超过9个
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的进程ID号
$@ 与$#相同,但是使用时加引号,并在引号中返回每个参数
$- 显示shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表示有错误
2.1.8影响变量的命令
declare
- 设置或显示变量
- -f 只显示函数名
- -r 创建只读变量(declare和typeset)
- -x 创建转出变量
- -i 创建整数变量
- 使用+替代-,可以颠倒选项的含义,-r例外
export
- 用于创建传给子shell的变量
- -- 表明选项结束,所有后续参数都是实参
- -f 表明在“名-值”对中的名字是函数名
- -n 把全局变量转换成局部变量,换句话说,命令的变量不再传给shell
- -p 显示全局变量列表
readonly
- 显示或设置只读变量
- -- 表明选项结束
- -f 创建只读变量
set
- 设置或重设各种shell
shift [n]
- 用于移动位置变量,调整位置变量,使$3的值赋于$2,$2的值赋于$1
typeset
- 用于显示或设置变量
- 是declare的同义词
unset
- 用于取消变量的定义
- -- 表明选项结束
- -f 删除只读变量,但不能取消从shell环境中删除指定的变量和函数。如PPID,PS1,等
2.2引号
2.2.1引用的必要性
变量和替换操作,在脚本中执行变量替换时最容易犯的错误就是引用错误
2.2.2双引号
可以引用除字符$、`、\外的任意字符或字符串
2.2.3单引号
让shell忽略任何引用值
2.2.4反引号
用于设置系统命令的输出到变量。shell将反引号中的内容作为一个系统命令,并执行其内容
2.2.5反斜杠
屏蔽字符特殊含义
2.3运算符
运算符是对计算机发出的指令
运算对象
- 数字、字符
- 变量
- 表达式 #运算符和运算对象的组合体
2.3.1运算符的类型
按位运算符 ~,<<,>>,&,|,^
~op1 反运算符,把op1中所有的二进制为1变为0,0变为1
op1<<op2 左移运算符,把op1中的二进制位向左移动op2位,忽略最左边移的各位,最右
端的各位补上0值,每做一次按位左移就有实现op1乘以2
op1>>op2 右移运算符,把op1中的二进制位向右移动op2位,忽略最右边移的各位,最左
端的各位补上0值,每做一次按位左移就有实现op1除以2
op1&op2 比较运算符,op1和op2对应位,对于每个二进制位来说,如果二者该位都是1,
则结果位1;否则,结果位为0
op1^op2 异或运算符,比较op1和op2对应位,对于每个二进制位来说,如果二者该位互补,
则结果位1;否则,结果位为0
op1|op2 或运算符,比较op1和op2对应位,对于每个二进制位来说,如果二者该位有一个
是1或都是1,则结果位1;否则,结果位为0
$[] 表示形式告诉shell对方括号中的表达式求值。
如#!/bin/bash
#$[]表示形式举例
echo $[3+9]
逻辑运算符
&& 与运算符
|| 或运算符
>,==,<,!= 大于,等于,小于,不等于运算符
赋值运算符
=,+=,-=,*=,/=,%=,&=,^=,|=,<<=,>>=
let $count=$count+$change
let $count+=$change
2.3.2表达式替换
$[]和$(()) 还是$[]吧,$[]可以接受不同基数的数字,如[bash#n]n表示基数2到36的任何基数
2.3.3运算的优先级 13最高
13 -,+ 正,负
12 |,~ 逻辑非,按位取反
11 *,/,% 乘,除,取模
10 +,- 加,减
9 <<,>> 按位左移,按位右移
8 <=,>=,<,> 小于等于,大于等于,小于,大于
7 ==,|= 等于,不等于
6 & 按位或
5 ^ 按位异或
4 | 按位或
3 && 逻辑与
2 | 按位或
1 =,+=,-=,*=,/=,%=,&=,^=,|=,<<=,>>= 赋值、运算且赋值
<3>shell输入与输出
3.1.1 echo #显示文本行或变量,或者把字符串输入到文件
echo [option] string
-e 解析转义字符
-n 回车不换行
转义符(\c,\f,\t,\n)
3.2.1 read #可以从键盘或文件的某一行文本中读入信息,并将其赋值给一个变量
read varible1 varible2 #如果只指定了一个变量,那read将会把所有的输入赋于该变量,直到遇到
第一个文件结束符或回车;如果给出了多个变量,它们按顺序分别被赋
于不同的变量。shell将用空格作为变量之间的分隔符
例:#!/bin/bash
#readname
echo -n "first name:"
read firstname
echo -n "last name:"
read lastname subname
echo -e "your first name is :${firstname}\n"
echo -e "your last name is :${lastname}\n"
echo -e "your subname is :${subname}\n"
3.3.1 cat #显示文件内容、创建文件,还可用它来显示控制字符
-v 显示控制字符
3.4.2 管道举例
df -k |awk '{print $1}' |grep -v "filesystem" #查看空间,查找第一列,过滤“Filesystem”
3.5.1 tee #把输出的一个副本输送到标准输出,另一个副本拷贝到相应的文件中,常用于管道之后
-a 将输入附加在文件的后头
3.5.2 tee举例
df -k |awk '{print $1}' |grep -v "filesystem" |tee partation.txt
3.6.1 标准输入、输出和错误
在shell中执行命令时,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件。
由于文件描述符难记,shell同时也给出了相应的文件名
文件 文件描述符
输入文件-标准输入 0(缺省是键盘,也可以是文件或其它命令的输出)
输出文件-标准输出 1(缺省是屏幕,也可以是文件)
错误输出文件-标准错误 2(缺省是屏幕,也可以是文件)
系统中实际上有12个文件描述符,可以任意使用文件描述符3-9
3.7.1 文件重定向
command > filename 把标准输出重定向到一个新文件中
command >> filename 把标准输出重定向到一个文件中(追加)
command 1 > filename 把标准输出重定向到一个文件中
command > filename 2>&1 把标准输出和标准错误一起重定向到一个文件中
command 2 > filename 把标准错误重定向到一个新文件中
command 2 >> filename 把标准错误重定向到一个新文件中(追加)
command >> filename 2>&1 把标准输出和标准错误重定向到一个新文件中(追加)
command < filename >filename2 command命令以filename作为标准输入,以filename2作为标准输出
command < filename command命令以filename作为标准输入
command << delimiter 从标准输入中读取,直到遇到delimiter分界符
command < &m 把文件描述符m作为标准输入
command > &m 把标准输出重定向到文件描述符m中
command < &- 关闭标准输入
3.7.2 重定向举例:
#cat >>eof.txt<<EOF
>hi,there is my centos
>he he
>bye
>EOF
#########################
grep "opoent" missiles 2>/dev/null
3.8.1 结合使用标准输出和标准错误
#cat acc_new acc_old.txt>acc.out 2>acc.err
合并使用标准输出和标准错误
切记shell是从左至右分析相应的命令
#grep "standard" standard.txt>grep.out 2>&1
3.9.1 exec #用于替代当前shell:并没启动子shell,使用这一命令时任何现有互不环境都将被清除,
并重新启动一个shell
exec command #command通常是个shell脚本,只有对文件描述符进行操作时,不会覆盖当前shell
3.10.1 文件描述符,exec与文件描述符结合
3-9文件描述符
例:#!/bin/bash
#file_desc
exec 3<&0 0<exec.txt
read line1
read line2
exec 0<&3
echo $line1
echo $line2
<4>控制流结构
4.1.1 流控制是
4.1.2 if语句
语句格式:
if 条件1 #如果条件1为真
then #那么
命令1 #执行命令1
elif 条件2 #如果条件1不成立
then #那么
命令2 #执行命令2
else #如果条件1,2均不成立
命令3 #那么执行命令3
fi #完成
#########################if语句必须以单词fi终止
if条件
then命令
fi
########################
例:
#!/bin/bash
#ifelif
echo -n "Enter your name:"
read NAME
if [ -z$NAME] || [ "$NAME" = "" ]
then
echo "You did not enter a name"
elif [ "$NAME" = "root" ];
then
echo "Hello root!"
elif [ "$NAME" = "john" ];
then
echo "Hello john!"
else
echo "You are not root or john,but hi $NAME"
fi
############################
4.2.1 case语句
####################
case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
esac
####################
例:
#!/bin/bash
#case select
echo -n "Enter a number from 1 to 3:"
read $ANS in
1)
echo "You select 1"
;;
2)
echo "You select 2"
;;
3)
echo "You select 3"
;;
y|Y)
echo "You select $ANS"
*)
echo "`basename $0`: This is not between 1 and 3" >&2
exit;
;;
esac
#############################################
4.3.1 for 循环
#############################################
for 变量名 in 列表
do
命令1
命令2
done
#############################################
4.4.1 until循环
#############################################
until 条件
do
命令1
命令2
done
注:条件可为任意测试条件,测试发生在循环末尾,因此循环到少执行一次
#############################################
#!/bin/sh
#until_mon
#监控分区
Part="~/"
#得到磁盘使用的百分比
LOOK_OUT=`df |grep $Part|awk '{print $5}'|sed 's/%//g'`
echo $LOOK_OUT
until [ "$LOOK_OUT" -gt "10" ]
do
echo "Filesystem ~/ is used 30%"
LOOK_OUT=`df |grep $Part|awk '{print $5}'|sed 's/%//g'`
sleep 5
done
################################################
4.5.1 while 循环
################################################
while 命令
do
命令1
命令2
……
done
注:在while和do之间虽然通常只使用一个命令,但可以放几个命令,命令通常用作测试条件。
################################################
#!/bin/bash
#whileread
echo "按住<ctrl>+D退出输入。"
while echo -n "您的尊姓大名?";read NAME
do
echo "没听过……${NAME}"
done
#############################################
4.6.1 break和continue控制
break [n]
退出循环
如果是在一个嵌入循环里,可以指定n来跳出的循环个数。
continue
跳过循环步
注:continue命令类似于break命令,只有一点重要差别,它不会跳出循环,只是跳过这个循环步。
#############################################
#!/bin/bash
#breakout
while :
do
echo -n "Enter any number [1……5] : "
read ANS
case $ANS in
1|2|3|4|5)
echo "You enter a number between 1 and 5."
break
;;
*)
echo "Wrong number,SB.Try again?(y/n):"
read IS_TRY
case $IS_TRY in
y|yes|Y|yes|YES)
continue
;;
*)
break
;;
esac
esac
done
#############################################
<5> 文本过滤
5.1 正则表达式
元字符用于匹配字符串
[] 只匹配[]内的内容,可以是一个单字符,也可是字符序列,可以用-表示范围,
如[1-3]=[123],[A-Za-z0-9]
. 只匹配任意单字符
pattern\{n\} 只用来匹配前面pattern出现次数,n为次数
pattern\{n,\} 只用来匹配前面pattern出现次数,次数最少为n
pattern\{n,m\} 只用来匹配前面pattern出现次数,次数为n与m之间
",',||,^,*,+ 特殊字符
#############################################
例:
IP ((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d)(\.((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d)){3}
域名 [a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?
5.12 find 命令举例(续)
xargs在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递
给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分
钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs
命令的用处所在,特别是与find命令一起使用。
find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全
部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并
如此继续下去。
在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并
非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统
性能下降的问题,因而效率不高;
而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的
参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内
核中相应的可调参数来确定。
例:
find . -type f -print | xargs file
find . -perm -7 -print | xargs chmod o-w
5.13 grep命令类名
[[:upper:]] [A-Z]
[[:alnum:]] [0-9a-zA-Z]
[[:lower:]] [a-z]
[[:space:]] 空格或tab
[[:digit:]] [0-9]
[[:alpha:]] [a-zA-Z]
5.14 awk介绍(续)
awk脚本由各种操作和模式组成
模式和动作
模式部分决定动作语句何时触发及触发事件(BEGIN,END)
动作对数据进行处理,放在大括号{}内指明(print)
分割符、域和记录
awk执行时,其浏览域标记为$!-$n。这种方法称为域标识。$0为所有域。
注意执行时不要混淆符号$和shell提示符$,它们是不同的。
5.16 合并与分割
uniq 从一个文本文件中去除或禁止重复行
<6> shell函数
6.1 函数定义
shell允许将一组命令集或语句形成一个可用块,这些块称为函数
#############################################
定义函数的格式
############
函数名 ()
{
命令1

}
############
function 函数名 ()
{

}
#############################################
#!/bin/bash
#hellofun
function hello () //GNU bash, version 3.2.39,加了function反而不行
{
echo "Hello,today is `date`"
return 0
}
hello
#############################################
6.2 参数传递
向函数传递参数就像在脚本中使用位置变数$1,$2…$9
#############################################
#!/bin/bash
#hellofun
function hello () //GNU bash, version 3.2.39,加了function反而不行
{
echo "Hello,$1 ,today is `date`"
return 0
}
hello SB
#############################################
6.3 函数文件
#############################################
#!/bin/bash
#func
#Source function
. hellofun.sh //引用函数一定要点空格
hello
#############################################
6.4 检查载入函数和删除函数
察看载入函数 set
删除函数 unset
6.6 函数返回状态值
#############################################
#!/bin/bash
#func
#Source function
. hellofun.sh //引用函数一定要点空格
hello
echo $?
#############################################
<7> 脚本参数传递
7.1 shift
7.2 getopts
##########################
##########高级Shell编程#######
##########################
<1>深入讨论
1.1 深入讨论awk
条件操作符
~ 匹配正则
!~ 不匹配正则
#############################################
#!/bin/bash
#awkif
echo "210-219网段的访问量是:`awk '{if ($1~/^21[0-9]/) print $()}' www.log|wc -l`"
#############################################
awk内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行-F选项
NF 浏览记录的域个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
awk字符串函数
gsub(r,s) 在整个$0中用s替代r
gsub(r,s,t) 在整个t中用s替代r
index(s,t) 返回s中字符串t的第一个字符
length(s) 返回s长度
match(s,r) 测试s是否包含匹配r的字符串
split(s,a,fs) 在fs上将s分成序列a
spring(fmt,exp) 返回经fmt格式化后的exp
sub(r,s) 用$0中最左边最长的子字符串代替s
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分
awk转义字符
\b 退格键
\t tab键
\f 走纸换页
\ddd 八进制值
\n 新行
\c 任意其他特殊字符,例如\\为反斜线符号
\r 回车键
printf修饰符
%c ASCII字符
%d 整数
%f 浮点数,例如(123.44)
%e 浮点数,科学记数法
%f 新行
%g awk决定使用哪种浮点数转换e或f
%o 八进制数
%s 字符串
%x 十六进制数
#############################################
#!/bin/bash
#This is show a menu
loopvar=2
#############
# main menu #
#############
main_menu()
{
echo
echo
dis_mainmenu="CREATE MINISITE IN CHENG.COM"
curdate=`date "+%Y-%m-%d %T"`
cat <<mayday
DATE : $curdate
====================================
$dis_mainmenu
====================================
** 1)ADD MINISITE ACCOUNT
** 2)ADD DOMAIN IN CHENG.COM
** 3)ADD DATABASE IN MYSQL
** 4)ADD VIRTUAL HOST IN APACHE
** 5)BACKUP MINISITE
** 6)DELETE MINISITE
** 7)EXIT
====================================
mayday
}

while [ $loopvar -gt 0 ]
do
main_menu
echo -n " Please choose [1-7]:"
read main_choice
case $main_choice in
7)
exit
;;
*)
clear
continue
;;
esac
done
#############################################
<2> shell工具
2.1 日志文件
#############################################
#!/bin/bash
#datelog.sh
#当前的日期
current_date=`date "+%Y%m%d"`
#今天的日志文件名
todaylog="testlog/${current_date}.log"
#如果日志目录不存在,创建一个
if [ ! -d testlog ]
then
mkdir testlog
fi
#如果日志文件不存在,创建一个
if [ ! -f $todaylog ]
then
touch $todaylog
fi
#输出日志到日志文件
log_time_format=`date "+%Y-%m-%d %T"`
echo "${log_time_format} 命令开始" >>$todaylog
#
# command blocks
sleep 4
#
#输出日志到日志文件
log_time_format=`date "+%Y-%m-%d %T"`
echo "${log_time_format} 命令结束" >>$todaylog
#############################################
2.2 信号
kill -l 列出所有信号
0退出shell信号,通常是CTRL-D
1挂起父进程被杀死
2来自键盘的中断信号,通常是CTRL-C
3从键盘退出
9无条件终止
11段(内存)冲突
15软件终止(缺省杀进程)
kill发送信号给进程
2.3 trap捕捉信号
信号可以被应用程序或脚本捕获,并依据该信号(1.2.3.15)采取相应的行动。
一些信号不能被捕获。如果一个命令收到信号9,就无法再捕捉其他信号。
捕捉到一个信号后,可以
1)不行动,由系统处理
2)忽略
3)采取相应的行动
2.4 eval
eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用
于那些一次扫描无法实现其功能的变量。
MYFILE="cat myfile"; `eval $MYFILE`
2.5 logger
logger命令向/var/log/message文件发送消息
格式一般为logger -p -i message
-p 为优先级,这也是缺省值
-i 在每个消息中记录发送消息的进程号
<3> 运行级别脚本介绍
3.1 运行级别
目录/etc/rcn.d
当前级别runlevel
运行级别目录文件格式SXXscript,KXXscript
3.2 启动应用程序
启动脚本分析(start|stop|restart)
/etc/init.d/下有很多脚本
<4> 几个脚本例子
#############################################
#!/bin/bash
#kill_process.sh
#只需要将firefox改为相应的进程即可
current_PID=$$
ps aux|grep "firefox"|grep -v "grep"|awk '{print $2}'>/tmp/${current_PID}.txt
for pid in `cat /tmp/${current_PID}.txt`
do
{
echo "Kill -9 $pid"
}
done
rm -f /tmp/${current_PID}.txt

Mysql备份脚本

Posted by – 2009-02-25

#!/bin/sh

#########################################
# Prim@Hosting Backup工具
# v2.0
# ValueOf.com
#########################################
EMAIL=0
#########################################
# 配置区
# the backup dir
BACKUP_BASE_DIR="/www/users/backup"

# 备份哪些?
WEB=0
EMAIL=0
DNS=0
MYSQL=1
CONTROL=1

# 测试模式?
testmode=0

# 本参数如设置为1,则打包压缩/www/users/目录时候,
# 将会把每个站点单独生成一个对应的tgz压缩文件
# 本参数如果为0,则/www/users/下所有站点将打包成为一个users.tar.gz的大文件
# 为了便于下载备份和解压缩备份文件,本参数默认设置为1
user_seperate=1

# 本参数如设置为1,则打包压缩/var/lib/mysql/目录时候,
# 将会把每个数据库单独生成一个对应的tgz压缩文件
# 本参数如果为0,则/var/lib/mysql/目录打包成为一个mysql.tar.gz的大文件
# 本参数默认设置为0
mysql_seperate=1

# 保留多少份旧的备份?
# 即除了当前最新的这个备份之外,还保留几个备份,最少为0个,默认为1
# 如果设为0,则只保留一个备份,每次备份的时候都会把以前的备份删除
max_old_backup=7

#########################################
# 以下的配置如果不明白最好不要改
#########################################
# 备份数据目录
WEB_DATA_DIR="/www/users"
EMAIL_DATA_DIR="/var/vmail"
DNS_DATA_DIR="/var/named"
CONTROL_DATA_DIR="/www/prima"
GENCOMSITE_DATA_DIR="/www/prima/htdocs/apps/GenComSite/sitepage /www/prima/htdocs/apps/GenComSite/upload"
COUNTER_DATA_DIR="/var/Counter"
system=`uname -a`
case "$system" in
Linux*) MYSQL_DATA_DIR="/var/lib/mysql" ;;
FreeBSD*) MYSQL_DATA_DIR="/var/db/mysql" ;;
*) MYSQL_DATA_DIR="/var/lib/mysql" ;;
esac

# 备份配置目录/文件位置
PRIMA_ETC_DIR="/usr/prima/etc"
PRIMA_CONF_FILE="$PRIMA_ETC_DIR/prima.conf"
POSTFIX_CONF_DIR="/usr/prima/postfix/conf"
FRONTPAGE_DIR="/usr/local/frontpage"
NAMED_CONF="/etc/named.conf"
RESIN_CONF="/usr/local/resin/host.conf"
TOMCAT_CONF="/var/tomcat4/conf/server.xml"
PHPMYADMIN_CONF="/www/prima/htdocs/apps/phpMyAdmin/config.inc.php"

# tar 参数
TAR_FLAG="zp"

#########################################
# 配置结束
# 下面的程序请不要改动
#########################################
# my functions
backup_list()
{
if [ -z "$1" ] || [ -z "$2" ] ; then
echo "backup_list() usage: backup_list data_to_backup backup_dir"
return 1
fi

list=$1
backup_dir=$2
for name in $list
do
echo
echo "do backup for $name"

prefix=`dirname $name`
self=`basename $name`
if [ -z "$prefix" ] || [ -z "$self" ] ; then
echo "Warning: can not fetch prefix/self for data $name, skip."
continue
fi

if [ -d "$name" ] ; then
cd $prefix
if [ "$testmode" = 1 ] ; then
cmd="tar $TAR_FLAG -c -f $backup_dir/$self.tar.gz $self"
echo $cmd
else
tar $TAR_FLAG -c -f $backup_dir/$self.tar.gz $self
fi
else
if [ -f "$name" ] ; then
if [ "$testmode" = 1 ] ; then
#cmd="cp -p $name $backup_dir/$self"
cmd="tar $TAR_FLAG -c -f $backup_dir/$self.tar.gz $name"
echo $cmd
else
#cp -p $name $backup_dir/$self
tar $TAR_FLAG -c -f $backup_dir/$self.tar.gz $name 2> /dev/null
fi
else
echo "Warning: data $name is not a dir or file, skip."
fi
fi

done

return 0
}

# function to clean old backup
clean_old_backup()
{
count=0
for name in `ls $BACKUP_BASE_DIR|grep -E '[0-9]{6,6}\-[0-9]{6,6}' | sort -r`
do
count=$((count+1))
if [ $count -gt $max_old_backup ] ; then
echo -n "Cleaning old backup: $name... "
if [ "$testmode" = 1 ] ; then
echo -n "rm -fr $BACKUP_BASE_DIR/$name"
else
if [ "$BACKUP_BASE_DIR/$name" = "/" ] ; then
echo "No rm -fr /!"
exit 1
fi
rm -fr $BACKUP_BASE_DIR/$name
fi
echo " Done."
else
echo "Keeping old backup: $name"
fi
done
}

# main process

echo "prima backup util"
datestr=`date '+%Y%m%d-%H%M%S'`
echo "date: $datestr"
echo

# clean old backup
clean_old_backup

# fetch data and config to be backuped
data_to_backup=""
user_to_backup=""
mysql_to_backup=""

if [ "$CONTROL" = "1" ] ; then
data_to_backup="$data_to_backup $CONTROL_DATA_DIR"
fi

if [ "$WEB" = "1" ] ; then
if [ "$user_seperate" = "1" ] ; then
user_dirs=`ls $WEB_DATA_DIR`
for x in $user_dirs;
do
x="$WEB_DATA_DIR/$x"
if [ -d $x ] ; then
user_to_backup="$user_to_backup $x"
fi
done
else
data=`grep ^home_base $PRIMA_CONF_FILE | awk -F '=' '{print $2}' 2>/dev/null`
if [ -z "$data" ] ; then
data=$WEB_DATA_DIR
fi
data_to_backup="$data_to_backup $data"
fi
fi
if [ "$EMAIL" = "1" ] ; then
data=`grep ^mail_space_base $PRIMA_CONF_FILE | awk -F '=' '{print $2}' 2>/dev/null`
if [ -z "$data" ] ; then
data=$EMAIL_DATA_DIR
fi
data_to_backup="$data_to_backup $data"
fi
if [ "$DNS" = "1" ] ; then
data=`grep ^zonefile_base $PRIMA_CONF_FILE | awk -F '=' '{print $2}' 2>/dev/null`
if [ -z "$data" ] ; then
data=$DNS_DATA_DIR
fi
data_to_backup="$data_to_backup $data"
fi
if [ "$MYSQL" = "1" ] ; then
if [ "$mysql_seperate" = "1" ] ; then
mysql_dirs=`ls $MYSQL_DATA_DIR`
for x in $mysql_dirs;
do
x="$MYSQL_DATA_DIR/$x"
if [ -d $x ] ; then
mysql_to_backup="$mysql_to_backup $x"
fi
done
else
data_to_backup="$data_to_backup $MYSQL_DATA_DIR"
fi
fi
data=`grep ^app_names $PRIMA_CONF_FILE | grep GenComSite 2>/dev/null`
if [ ! -z "$data" ] ; then
data=$GENCOMSITE_DATA_DIR
fi
data_to_backup="$data_to_backup $data"

data=`grep ^app_names $PRIMA_CONF_FILE | grep CounterConfig 2>/dev/null`
if [ ! -z "$data" ] ; then
data=$COUNTER_DATA_DIR
fi
data_to_backup="$data_to_backup $data"

echo
echo "data_to_backup: $data_to_backup"
echo
if [ "$user_seperate" = "1" ] ; then
echo
echo "user_to_backup: $user_to_backup"
echo
fi
if [ "$mysql_seperate" = "1" ] ; then
echo
echo "mysql_to_backup: $mysql_to_backup"
echo
fi

conf_to_backup=""
if [ "$WEB" = "1" ] || [ "$EMAIL" = "1" ] || [ "$DNS" = "1" ] || [ "$MYSQL" = "1" ] ; then
conf_to_backup="$conf_to_backup $PRIMA_ETC_DIR"
fi
if [ "$WEB" = "1" ] ; then
resin=`grep ^use_mod_caucho $PRIMA_CONF_FILE | awk -F '=' '{print $2}' 2>/dev/null`
if [ -z "$resin" ] ; then
conf_to_backup="$conf_to_backup $RESIN_CONF"
fi
tomcat=`grep ^use_mod_jk $PRIMA_CONF_FILE | awk -F '=' '{print $2}' 2>/dev/null`
# if [ -z "$tomcat" ] ; then
# conf_to_backup="$conf_to_backup $TOMCAT_CONF"
# fi
fi
if [ "$EMAIL" = "1" ] ; then
conf_to_backup="$conf_to_backup $POSTFIX_CONF_DIR"
fi
if [ "$DNS" = "1" ] ; then
data=`grep ^named_conf $PRIMA_CONF_FILE | awk -F '=' '{print $2}' 2>/dev/null`
if [ -z "$data" ] ; then
data=$NAMED_CONF
fi
conf_to_backup="$conf_to_backup $data"
fi
if [ "$MYSQL" = "1" ] ; then
conf_to_backup="$conf_to_backup $PHPMYADMIN_CONF"
fi

echo
echo "conf_to_backup: $conf_to_backup"
echo

# create backup dir
if [ ! -d "$BACKUP_BASE_DIR" ] ; then
echo "Warning: backup base dir $BACKUP_BASE_DIR does not exist."
echo "I will create one for you."
fi

base_dir="$BACKUP_BASE_DIR/$datestr"
mkdir -p -m 700 $base_dir
if [ $? != 0 ] ; then
echo "Error: backup dir $base_dir create failed."
exit 1
fi

umask 066

# backup data
data_backup_dir="$base_dir/data"
mkdir -p -m 700 $data_backup_dir

backup_list "$data_to_backup" $data_backup_dir

# backup conf
conf_backup_dir="$base_dir/data/conf"
mkdir -p -m 700 $conf_backup_dir

backup_list "$conf_to_backup" $conf_backup_dir

#backup user_site
if [ "$user_seperate" = "1" ] ; then
user_backup_dir="$base_dir/data/users"
mkdir -p -m 700 $user_backup_dir
backup_list "$user_to_backup" $user_backup_dir
fi

#backup mysql
if [ "$mysql_seperate" = "1" ] ; then
mysql_backup_dir="$base_dir/data/mysql"
mkdir -p -m 700 $mysql_backup_dir
backup_list "$mysql_to_backup" $mysql_backup_dir
fi