Shell编程(脚本)的常用命令和语句
一些常用的Shell编程(脚本)命令和语句,可以满足一般需求。
接收到的命令参数:
参数个数:$#
参数值:命令本身:$0第一个参数:$1第二个参数:$2……
退出命令:exit
echo命令:
换行:echo
输出后不换行:echo-n"请选择(y/n)?"
利用转义符号输出双引号:echo"欢迎使用\"正式服务器\"部署工具。"
输出中带变量:echo"即将部署项目:$project_name"
输出带转义符的字符串:echo-e"first\tsecond"
输出到文件追加到文件尾:echo-e$log_info>>deploy.log覆盖文件内容:echo-e$log_info>deploy.log
printf命令:(可以代替echo,格式化输出,和C语言中的printf函数功能相同)
输出一个小数点后两位的数,并换行:printf"Thenumberis%.2f.\n"100
输出一个指定宽度的字符串:左对齐:printf"%-20s%-15s%10.2f\n""Stephen""Liu"35右对齐:printf"|%10s|\n"hello
变量:
定义:profile="production"
使用:echo$profile
变量拼接:log_info="$log_info,$target_ip"
数组:
定义:servers=("192.168.0.31""192.168.0.39")projects=("public""industry""logistics""misc")
获得整个数组:${projects
}获得数组元素个数:${#servers[@]}if语句(条件判断同样适用于while语句和for语句):
判断一个变量(project)是否非空:if[$project];thenecho"Variable\"project\"isnull."fi
判断不等于:if[$#-ne3];thenecho"命令行参数不是3个"fi
布尔值判断:if["$is_ip_correct"=false];thenecho"无效的ip地址,请使用下面ip之一:"echo${servers
}exitfi字符串相等判断:if["$confirm"=="y"]&&["$confirm"!="n"];do#dosomething...fi正则表达式判断if[[$1=~^public|industry$]]&&[[$3=~^[yn]$]];then#dosomething...fi
if[[!$deploy_more=~[yn]]];then#dosomething...fi
判断文件是否存在:if[!-ftarget/$project.war];then#dosomething...
fi
判断目录是否存在:if[-d$2/webapps/$1];then#dosomething...fi
判断一个文件名(字符串)的后缀backup_file="/backup/java_data/$1-$today.war"backup_file="/backup/java_data/$1-$today.gz"
if["${backup_file##*.}"="war"];thencp$backup_file$1.warelif["${backup_file##*.}"="gz"];thentarzxvf$backup_fileelseecho"备份文件格式不对"exitfi
read语句(读取用户输入的字符串):
最简单的用法:读取用户输入到变量yes_or_noreadyes_or_no
提示用户输入y或nread-e-p"是否备份:(y/n)?"-i"y"needbackup(参数说明:-e:不知有什么用,但如果去掉了,-i就失效了;-p:后面接着提示语句;-i:后面接着缺省输入;最后一个参数是保存用户输入的变量。)
select语句(提示用户从列表中选择一个):
修改默认提示语(默认值是"#?"):PS3="请选择一个项目:"
提示用户从数组中选择一个值:selectprojectin${projects
};doif[$project];thenbreakfidone或加上退出条件:selecttarget_ipin${servers}"Exit(退出)";doif["$target_ip"="Exit(退出)"];thenecho"谢谢使用!Good-Bye!"breakfiif[$target_ip];then#dosomethingfidonecase语句:case$projectinpublic)project_name="大众版";;logistics)project_name="配送版";;misc)project_name="杂项版";;esac
while语句:
配合正则表达式判断使用:while[[!$needbackup=~^[yn]$]];doread-e-p"是否备份:(y/n)?"-i"y"needbackupdone
用“...”做进度条echo-n"等待$port端口打开……"while[!$pid_new];do#sleep1pid_new=`netstat-nlp|grep$port|awk'{print$7}'|awk-F"/"'{print$1}'`echo-n"…"done
for语句:
遍历:forip_tin${servers
};doif["$2"="$ip_t"];thenis_ip_correct=truebreakfidone调用其他程序:使用``,并获得输出结果:PS3="请选择一个分支:"selectbranchin`svnlistsvn:///java/code/branches`;doif[$branch];thensvn_dir="svn:///java/code/branches/$branch"project_dir=$branchbreakfidone
使用$(),并获得输出结果:today=$(date+%Y-%m-%d/%H:%M:%S)svn_version=$(svninfo$svn_dir|grep"LastChangedRev:"|awk'{print$4}')
无声地调用其他程序(不输出结果,即把结果输出到一个null设备中)rm$2/logs/m*$2/logs/l*$2/logs/h*$2/logs/catalina.2015*&>/dev/null&
awk(用来对字符串进行切片处理,一般配合grep使用):
获得以空格分隔的第四个字符串:svn_version=$(svninfo$svn_dir|grep"LastChangedRev:"|awk'{print$4}')
获得以特殊分隔符("/")分隔的第一个字符串awk-F"/"'{print$1}'
获取所有端口号为$port的进程,并杀掉forpidin`netstat-nlp|grep$port|awk'{print$7}'|awk-F"/"'{print$1}'`doecho"==========================Warning========================"echo"无法正常关闭进程,端口:$port,直接kill掉,进程号:$pid"echo"==========================Warning========================"kill$piddone