shell 脚本如何编写-致初学者

一些写脚本经验, 仅供参考, 对于写 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

你可能感兴趣的:(shell运维初学者)