1.1 格式
1. shell脚本,一行可以写多个命令,但注意命令之间要用 ;隔开,如果一行只写一个命令则不用写;即可
shell变量大全:
分为三类:普通的变量 环境变量 特殊位置的变量:URL shell变量大全:http://zccst.iteye.com/blog/1135109
export 变量 /etc/profile ~/.bash_profile ~/.bashrc
http://blog.sina.com.cn/s/blog_67146a750100y6zr.html
http://linux.chinaunix.net/doc/system/2005-02-03/1084.shtml
2. 测试命令
[ -d DIR ] | 如果DIR 存在并且是一个目录则为真 |
[ -f FILE ] | 如果FILE 存在且是一个普通文件则为真如果FILE文件不为空,文件里面有数据则是真 如果FILE文件为空,文件里面没有数据则是真 |
[ -z STRING ] | 如果STRING 的长度为零则为真 |
[ -n STRING ] | 如果STRING 的长度非零则为真 |
[ STRING1 = STRING2 ] | 如果两个字符串相同则为真 |
[ STRING1 != STRING2 ] | 如果字符串不相同则为真 |
[ ARG1 OP ARG2 ] | ARG1 和ARG2 应该是整数或者取值为整数的变量,OP 是-eq (等于)-ne (不等于)-lt (小于)-le (小于等于)-gt (大于)-ge (大于等于)之中的一个 |
整数、字符串比较的格式:
http://www.cnblogs.com/happyhotty/articles/2065412.html
和C语言类似,测试条件之间还可以做与、或、非逻辑运算:
[ ! EXPR ] | EXPR 可以是上表中的任意一种测试条件,!表示逻辑反 |
[ EXPR1 -a EXPR2 ] | EXPR1 和EXPR2 可以是上表中的任意一种测试条件,-a 表示逻辑与 |
[ EXPR1 -o EXPR2 ] | EXPR1 和EXPR2 可以是上表中的任意一种测试条件,-o 表示逻辑或 |
2. if/elseif/else 格式
#!/bin/bash
name=$1
if [ $name = "shuming" ];then
echo "hello,shuming"
elif [ $name = "caohong" ]; then
echo "hello,caohong"
else
echo "hello,erverone"
fi
(1) if [ elif [ 之间必须用
空格隔开,否则会有语法错误
(2) elif ----->并不是 elseif
(3) ] then之间用;隔开,一般再加上一个空格
(4) 一定要以 fi 来标识if 结构的结束
(5) 比较大小[] 的注意事项:两边要空格隔开,-eq -ne -gt -lt -ge -le
if else 格式也可以用&& 来实现,command1 && command2只有在command1成功执行后才会执行command2
test "$(whoami)" != "root" && echo "it is net root running!"
如果whoami 是root 则不会执行后面的语句
#/bin/bash
kfc_proc_count=`ps -u ads|grep kfc|wc -l`;
disp_proc_count=`ps -u ads|grep dispatch|wc -l`;
ret=`ps aux|grep ads|grep -v grep|grep dispatch`;
ret_wc=`ps aux|grep ads|grep -v grep|grep dispatch|wc -l`;
isbindip=`/sbin/ifconfig|grep 172.24.130.33|wc -l`;
ismain=`echo $ret|grep main|wc -l`; ---->echo cat的区别
isext=`echo $ret|grep ext|wc -l`;
if [ $kfc_proc_count = 1 ] && [ $disp_proc_count = 1 ];then ---> && || 的使用方法
if [ $ismain = 1 ] && [ $isbindip = 1 ]; then
main_ext_OK=1;
elif [ $isext = 1 ] && [ $isbindip = 0 ]; then
main_ext_OK=1;
else
main_ext_OK=0;
fi
else
main_ext_OK=0;
fi
if [ -f "$file" -a `cat $file 2>/dev/null|grep -v '^#'|grep "$key"|wc -l` -gt 0 ]; then
return 0
else
return 1
fi
3. case/esac 结构
case 命令可类比C中的switch/case语句,esac表示case语句的结束。C语言的case只能匹配整型或字符型常量表达式,而shell 脚本的case可以匹配字符串和Wildcard,每个匹配分支可以有若干条命令,末尾必须以 ;; 结束,执行时找到第一个匹配的分支并执行相应的命令,然后直接跳到esac之后,不需要像C语言那样break跳出。
#!/bin/bash
echo "Is it morning? Please answer yes or no."
read yes_or_no
case "$yes_or_no" in
yes|y|YES|Y)
echo "Good morning";;
[nN]*)
echo "Good afternon";;
*)
echo "It is error"
esac
(1)case 变量 in
(2) 对应的值) 只有半个括号
(3)每个分支对应命令后面是 ;; 隔开,最后一个不用!
(4) esac结束case语句
#!/bin/bash
case $1 in
start)
echo "start the process of apache"
echo "ok,start";;
stop)
echo "stop the process of apache";;
restart)
echo "restart the process of apache";;
reload|force-reload)
echo "reload the configfile";;
*)
echo "It is error"
esac
4. for/do/done 循环
#!/bin/bash
for var in cao shu ming
do
echo "I like $var"
echo "Hello everyone"
done
(1) var 是一个变量(自己设定即可),in 后是一个 字符串行
(2) do ------done
#!/bin/bash
for var in $(awk -F: '{print $1}' /home/caoshuming.pt/t.txt)
do
echo "I like $var"
echo "Hello everyone"
done
打印的结果是:
[caoshuming.pt@ecpmv152197.cm3 ~]$ ./shuming.sh
I like shuming
Hello everyone
I like caohong
Hello everyone
I like liuchao
Hello everyone
字符串行不一定是一系列字符串累加起来,可能是其他命令的结果。
for循环用法大全:
http://hi.baidu.com/plp_cm/blog/item/d828d1881b05e2faf11f3607.html
4. while/do/done 结构
#!/bin/bash
num=0
while [ $num -ne 10 ]
do
echo "please inter number"
read num
done
echo "the num is 10"
(1) do done 结构
(2) 判断条件 [ ***** ]
#!/bin/bash
2 while read line
3 do
4 echo $line
5 done < t.txt
读取文件t.txt 里面的数据,以每一行为基准:
[caoshuming.pt@ecpmv152197.cm3 ~]$ ./shuming.sh
dkdkjfafja
aaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbb
cccccccccccccccccc
eeeeeeeeeeeeeeeeee
5. 函数结构
#/bin/bash
is_directory()
{
DIR_NAME=$1
if [ ! -d $DIR_NAME ]; then
return 1
else
return 0
fi
}
for DIR in "$@"; do
if is_directory "$DIR"
then :
else
echo "$DIR doesn't exist. Creating it now..."
mkdir $DIR > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Cannot create directory $DIR"
exit 1
fi
fi
done
(1) 函数要先定义后调用
(2) 函数里面的$1 $2 就是调用函数后面的 参数,$1 $2在函数内部改变不影响外部的参数
(3) 如果{ 与命令在一行,则必须用空格隔开,多个命令在同一行用 ; 隔开,而且如果最后一个命令与} 在同一行,则命令后面加;
(4). 函数直接调用 is_directory "dir" 如果返回值把返回值设成 整数:0 1 2 3 a=$? 来获取返回值即可
(5). exit 0 调出脚本 结束整个 .sh 的执行
6. 判断文件、目录是否存在
#!/bin/sh
myPath="/var/log/httpd/"
myFile="/var /log/httpd/access.log"
#这里的-x 参数判断$myPath是否存在并且是否具有可执行权限
if [ ! -x "$myPath"]; then
mkdir "$myPath"
fi
#这里的-d 参数判断$myPath是否存在
if [ ! -d "$myPath"]; then
mkdir "$myPath"
fi
#这里的-f参数判断$myFile是否存在
if [ ! -f "$myFile" ]; then
touch "$myFile"
fi
#其他参数还有-n,-n是判断一个变量是否是否有值
if [ ! -n "$myVar" ]; then
echo "$myVar is empty"
exit 0
fi
#两个变量判断是否相等
if [ "$var1" = "$var2" ]; then
echo '$var1 eq $var2'
else
echo '$var1 not eq $var2'
fi
3. 判断普通文件是 [ -f $file ] 路径是 [ -d path ] 如果不管文件还是路径只是判断其是否存在则用-e 参数 [ -e /.../ ]
#!/bin/bash
logfile=$1
keywords=$2
filterwords=$3
timestamp=`date +%s`
if [ ! -f $logfile ];then
rescount=0
exit
else
#last 2 minutes
last_one_min=$(date -d "-1 minute" "+%Y-%m-%d %H:%M")
last_two_min=$(date "+%Y-%m-%d %H:%M" -d "-2 minute")
if [ "X$filterwords" = "X" ];then
grepcmd="egrep '$last_one_min|$last_two_min'|egrep -i '$keywords'"
else
grepcmd="egrep '$last_one_min|$last_two_min'|egrep -i '$keywords'|egrep -v '$filterwords'"
fi
#---test-----
echo -e "grepcmd=$grepcmd\t"
echo "logfile=$logfile "
# count of error log
rescount=$(cat $logfile|eval $grepcmd|wc -l )
fi
echo -e "$timestamp\t rescount=$rescount"
其中要注意:eval 的用法:eval的功能是在执行命令前首先扫描命令进行 所有的的替换,eval 用在一次扫描不能完全替换的情况下,eval可以进行两次扫描,确保把命令中的变量和其他非直接用的都替换。