一些写脚本经验, 仅供参考, 对于写 jenkins 脚本和运维有用
脚本文件
#! /bin/bash
# scripts write here
变量
# 赋值 = 两边不能有空格
var=xxx
# 局部变量; 默认全是全局变量
local var=xxx
# 参数, 从脚本外来的参数为 $1, $2, $3 ; 一般在脚本开始将其重命名赋值
param1=$1
# 数组 用空格分开
array=(var1 var2 var3)
# 变量中的变量;
image=app
appTar=/home/apps/app.tar
image_path=$(eval echo '$'${image}'Tar')
load_result=`docker load < $image_path`
# 字符串拼接
# shell 中的字符串拼接不用任何连接符, 直接写后面就可以
var1=xx
var2=bbb
var3="${var1}${var2}foo"
echo $var3
输出
# echo 打印不换行
echo -n "输出字符"
输入
# 输入提示
read -p "提示语: " var
echo $var
# 输入数组, 每个项要用空格分隔
read -p "input array: " array
for ((i=0; i<${#array[@]}; i++)){
item=${array[i]}
echo $item
}
# 输入目录, 输入目录时可以使用 tab
read -p "input dir: " -e path
echo $path
程序控制
if 分支
# if空格[空格<变量>空格==空格<变量>空格];空格then
if [ "x" == "x${version}" ]; then
# do if
else
# do else
fi
条件判断中, 由于 shell 对于>
<
等字符敏感, 所以, 大于, 小于写成 gt lt 形式
case 分支
case $var in
"value1")
# do value1
;;
"*")
# do not catch
;;
esac
case 分支一般用来处理选择分支程序, 如果输入项没有满足要求, 则最后打印使用说明
usage() {
echo "Usage: sh server.sh [start|stop]"
exit 1
}
case "$1" in
"start")
start
;;
"stop")
stop
;;
"*")
usage
;;
esac
for 循环
array=(1 2 3)
for ((i=0; i<${#array[@]}; i++)){
item=${array[i]}
echo $item
}
这种 for 循环比较符合常规编程语言, 所以我一般喜欢用这个 for 循环
用 find 命令查到的文件, 可以使用 for in 来操作
sqlfiles=`find . -name "*.sql"`
for sqlfile in $sqlfiles
do
echo $sqlfile
done
函数
# 函数声明, 也需要先声明才能使用
function fun(){
param1=$1
param2=$2
# some scripts
result=xxx
return 1
}
# 函数调用
fun "mm" 1
echo $?
echo "fun result is: $result"
shell 中函数的参数和返回值和其它程序中不太一样
参数: 和 shell 脚本一样, 参数名为 $1 $2 $3 ...
返回值: 只能返回数字, 调用处使用 $? 接收 表示上条命令的执行结果; 注意: 要立即接收, 这个只能表示上一条命令的执行结果, 不然下一条命令一执行, 这个值就没了
一般使用全局变量来传递函数的返回值, 因为它的返回值功能实在是太弱了
模块
单独的功能另启脚本来写, 调用另一个脚本
sh script.sh
参数: 和调脚本参数一样 $1 $2 $3
返回值: 返回值需要使用 export 暴露出来, 调用处的脚本才能访问到
export var=xxxx
删除命令注意事项
在写脚本的时候, 一定要慎用 rm, 不确定时可以用 mv 命令, 移动到别的地方
# 危险指令, 当 var1 为空时
var1='某个指令执行的结果'
rm -f /$var1
完整的示例
#!/bin/sh
# 获取本机 iplocal_ip(){
local_ip=`ip add | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}' | cut -d'/' -f 1 | head -n 1`
#echo ">> 获取本机IP 为: $local_ip"
echo $local_ip
}
## java env
# export JAVA_HOME=/usr/local/jdk/jdk1.8.0_101
export JRE_HOME=$JAVA_HOME/jre
# extend lib path
libpath=sanritoolslib
# 本机 ipip=$(local_ip)
# Java opts
JAVA_OPTS="-Xms256m -Xmx256m -Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=$ip"
echo "JAVA_OPTS:${JAVA_OPTS}"
API_NAME=sanritools
JAR_NAME=$API_NAME\.jar
#PID 代表是PID文件
PID=$API_NAME\.pid
#使用说明,用来提示输入参数
usage() {
echo "Usage: sh server.sh [start|stop|restart|status]"
exit 1
}
#检查程序是否在运行
is_exist(){
pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' `
#如果不存在返回1,存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
#启动方法
start(){
is_exist
if [ $? -eq "0" ]; then
echo ">>> ${JAR_NAME} is already running PID=${pid} <<<" else
nohup $JRE_HOME/bin/java -Dloader.path=$libpath $JAVA_OPTS -jar $JAR_NAME >/dev/null 2>&1 &
echo $! > $PID
echo ">>> start $JAR_NAME successed PID=$! <<<" fi
}
#停止方法
stop(){
#is_exist
pidf=$(cat $PID)
#echo "$pidf"
echo ">>> api PID = $pidf begin kill $pidf <<<" kill $pidf
rm -rf $PID
sleep 2
is_exist
if [ $? -eq "0" ]; then
echo ">>> api 2 PID = $pid begin kill -9 $pid <<<" kill -9 $pid
sleep 2
echo ">>> $JAR_NAME process stopped <<<" else
echo ">>> ${JAR_NAME} is not running <<<" fi
}
#输出运行状态
status(){
is_exist
if [ $? -eq "0" ]; then
echo ">>> ${JAR_NAME} is running PID is ${pid} <<<" else
echo ">>> ${JAR_NAME} is not running <<<" fi
}
#重启
restart(){
stop
start}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
"*")
usage
;;
esac
exit 0
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。