乐趣区

LINUX-shell-脚本讲解

  • 注释一个常用的 shell 脚本,理解了里面用的语法和命令,就可以自己去写 shell 脚本了。
\#!/bin/bash
\# 功能:拷贝远程机器的 model 文件到本机

set -u # 遇到不存在的变量就会报错,并停止执行
set -x # 进入跟踪方式,显示所执行的每一条命令

work_dir=$(readlink -f $(dirname $0)) # 获取脚本所在的目录,并赋值给变量,$0 表示 当前脚本的文件名 

if [$# -eq 1]; then # shell 的 if 语句,括号内的空格不能少,$# 表示传递给脚本或函数的参数个数,-eq 判断两个数字是相等
    date=$1 # $1 表示传递给脚本表示第一个参数
    env="prod" # 变量的赋值
elif [$# -eq 2]; then
    date=$1
    env=$2 # $2 表示传递给脚本表示第二个参数
else
    date=$(date -d "1 day ago" +"%Y-%m-%d 00:00:00") # 这里的 $(command) 是固定用法,将 command 的结果赋值给 date 这个变量
    env="prod"
fi

dingtalk_webhook="https://oapi.dingtalk.com/robot/send?access_token=some_token"
function dingtalk_request(){ # 在 shell 中定义一个函数
    curl -H "Content-type: application/json" -X POST -d '{"msgtype":"text","text": {"content":"'$message'"}}' $dingtalk_webhook
}

local_path="/path/to/local"
date_suffix=$(date -d "$date" +"%Y%m%d") # 这里三个变量都是通过命令获取到具体的值
date_now=$(date +"%Y-%m-%d_%H:%M:%S")
host_name=$(hostname)

remote_host="hostname_test"
remote_path="/path/to/remote_test"
if [$env = "prod"]; then # shell 中字符串比较是否相等用 =
    remote_host="hostname_prod"
    remote_path="/path/to/remote_prod"
fi

test -e $local_path/copy_tag/done.$date_suffix # test -e 命令来查看文件是否存在,$date_suffix 表示获取 date_suffix 这个变量的值
if [$? -eq 0]; then # $? 表示上一条命令(即 test -e,文件存在返回值为 0)的返回值;如果本地有 done 文件,说明已经拷贝过了,就不用重复拷贝
    echo "$local_path/copy_tag/done.$date_suffix exist" # echo 向屏幕打印一条信息
    exit 0 # shell 脚本正常退出,返回值是 0(脚本执行完,0 可以通过 $? 获取,即上一条命令的返回值)fi

ssh $remote_host "test -e $remote_path/model.$date_suffix" # 使用 ssh 命令到远程机器上执行 test 命令
if [$? -ne 0]; then # -ne 用来判断数字不相等;远程机器的 model 文件还没有生成,退出
    echo "$remote_path/model.$date_suffix not exist"
    exit -1 # shell 脚本异常退出,返回值是 -1
fi

file_flag=$(head $local_path/flag) # head 命令打印文件中内容(内容只用一行,0 或者 1),并赋值给 file_flag
current_file_flag="0"
if [$file_flag -eq 0]; then
    current_file_flag="1"
elif [$file_flag -eq 1]; then
    current_file_flag="0"
else
    message="[$host_name]Discp_reomte_model_failed:Get_invalid_flag_$file_flag[$date_now]" # 将多个变量和一些信息拼接成字符串
    echo $message
    dingtalk_request # 调用之前定义的函数
    exit -1
fi

scp $remote_host:$remote_path/model.$date_suffix $local_path/$current_file_flag/modelFile # 将远程机器的文件拷贝到本地
if [$? -ne 0]; then # 拷贝失败,即返回值不为 0,就发送钉钉报警,并退出
    message="[$host_name]Discp_reomte_model_failed:$remote_path/model.$date_suffix[$date_now]"
    echo $message
    dingtalk_request
    exit -1
fi

echo "$current_file_flag" > $local_path/flag # 将信息(current_file_flag 的值)重定向到指定文件中,即 shell 的写文件
echo "$current_file_flag" > $local_path/copy_tag/model.done.$date_suffix

md5sum $local_path/$current_file_flag/modelFile # md5sum 用来查看文件的 md5 值
ssh $remote_host "md5sum $remote_path/model.$date_suffix" # 查看远程机器文件的 md5 值,这两条命令记录下 md5,用来检查文件是否一致

message="[$host_name]Discp_reomte_model_success_to_$local_path/$current_file_flag/modelFile[$date_now]" 
echo $message # 拷贝成功,打印信息
dingtalk_request # 拷贝成功,发送钉钉信息 
退出移动版