工作中,为了解决一些问题或者自动处理一些繁琐的操作,我常常会写一些脚本。
每次写脚本也花了不少时间,这里记录一下几个工作中用到的脚本,之后再用到的时候找起来容易些~
推荐文章:Hello系列 | Shell编程必备简明基础知识
1、一键配置脚本
#! /bin/bash
#####################################################################
# 脚本功能:一键配置脚本
#####################################################################
echo "################################# 解压、拷贝文件 #################################"
# 解压安装文件
tar xf robot_install_files.tar
echo "tar xf robot_install_files.tar"
SRC_INSTALL_FILE_PATH=./robot_install_files
ROBOT_USR_PATH=/data
# mqtt
mv ${SRC_INSTALL_FILE_PATH}/mqtt ${ROBOT_USR_PATH}
echo "mv ${SRC_INSTALL_FILE_PATH}/mqtt ${ROBOT_USR_PATH}"
# rsync
mv ${SRC_INSTALL_FILE_PATH}/rsync /usr/bin
echo "mv ${SRC_INSTALL_FILE_PATH}/rsync /usr/bin"
# bin
SRC_BIN_DIR=${SRC_INSTALL_FILE_PATH}/bin
DEST_BIN_DIR=/data/bin
if [ -d ${DEST_BIN_DIR} ]; then
echo "${DEST_BIN_DIR} exit, cp config"
cp ${SRC_BIN_DIR}/* ${DEST_BIN_DIR}
else
echo "${DEST_BIN_DIR} not exit, mv config"
mv ${SRC_BIN_DIR} ${ROBOT_USR_PATH}
fi
# cfg
SRC_CFG_DIR=${SRC_INSTALL_FILE_PATH}/cfg
DEST_CFG_DIR=/data/cfg
if [ -d ${DEST_CFG_DIR} ]; then
echo "${DEST_CFG_DIR} exit, cp config"
cp ${SRC_CFG_DIR}/* ${DEST_CFG_DIR}
else
echo "${DEST_CFG_DIR} not exit, mv config"
mv ${SRC_CFG_DIR} ${ROBOT_USR_PATH}
fi
# lib
SRC_LIB_DIR=${SRC_INSTALL_FILE_PATH}/lib
DEST_LIB_DIR=/data/lib
if [ -d ${DEST_LIB_DIR} ]; then
echo "${DEST_LIB_DIR} exit, cp config"
cp ${SRC_LIB_DIR}/* ${DEST_LIB_DIR}
else
echo "${DEST_LIB_DIR} not exit, mv config"
mv ${SRC_LIB_DIR} ${ROBOT_USR_PATH}
fi
chmod 777 ${ROBOT_USR_PATH}/bin/*
echo "################################# thttpd配置 #################################"
CURRENT_DIR=$PWD
WEB_PAGE_SRC_DIR=${SRC_INSTALL_FILE_PATH}/webpage
cp ${CURRENT_DIR}/mqtt/lib/libmos* /lib/
mkdir -p /etc/thttpd
chmod 755 /etc/thttpd
touch /etc/thttpd/thttpd.log
chmod 666 /etc/thttpd/thttpd.log
touch /etc/thttpd/thttpd.pid
chmod 666 /etc/thttpd/thttpd.pid
mkdir -p /etc/thttpd/html
chmod 755 /etc/thttpd/html
mkdir -p /etc/thttpd/html/cgi-bin
chmod 755 /etc/thttpd/html/cgi-bin
cp ${WEB_PAGE_SRC_DIR}/thttpd.conf /etc
chmod 777 /etc/thttpd.conf
cp ${WEB_PAGE_SRC_DIR}/index.html /etc/thttpd/html
chmod 644 /etc/thttpd/html/index.html
cp -r ${WEB_PAGE_SRC_DIR}/jquery /etc/thttpd/html
chmod 777 /etc/thttpd/html/jquery
chmod 666 /etc/thttpd/html/jquery/*
cp ${WEB_PAGE_SRC_DIR}/thttpd /bin
chmod 777 /bin/thttpd
cp ${WEB_PAGE_SRC_DIR}/MowerHTML.cgi /etc/thttpd/html/cgi-bin
chmod 755 /etc/thttpd/html/cgi-bin/MowerHTML.cgi
echo "################################# 配置环境变量 #################################"
echo "${CURRENT_DIR}"
if [ -d ${ROBOT_USR_PATH}/mqtt ]; then
echo "export LD_LIBRARY_PATH=$CURRENT_DIR/mqtt/lib/:/data/lib:$LD_LIBRARY_PATH" >> /etc/profile
echo "export PATH=$CURRENT_DIR/mqtt/bin/:$CURRENT_DIR/mqtt/sbin:$PATH" >> /etc/profile
echo "user root" >> $CURRENT_DIR/mqtt/etc/mosquitto/mosquitto.conf
echo "mosquitto -d -c $CURRENT_DIR/mqtt/etc/mosquitto/mosquitto.conf" >> /etc/profile
echo "cd /data/bin/" >> /etc/profile
echo "pwd" >> /etc/profile
source /etc/profile
else
echo "mqtt not exit"
fi
echo "############################### 删除解压文件 ###############################"
rm -rf /data/robot_install_files
echo "rm -rf robot_install_files"
每次装新机器都需要安装一些文件、进行一些必要配置,把这些繁琐的工作交给脚本。
2、log并自动合并
#!/bin/bash
#####################################################################
# 脚本功能:一键获取log并自动合并
#####################################################################
# 机器IP
ROBOT_IP=172.13.10.36
# PC端存log的路径
PC_SAVE_LOG_PATH=.
APP_LOG_TMP_PATH=${PC_SAVE_LOG_PATH}/app_tmp_dir
# 合成的文件
APP_MERGE_LOG_FILE=${PC_SAVE_LOG_PATH}/app_log_$(date +%m%d_%H%M)
# 机器log路径(不可修改!)
ROBOT_APP_LOG_PATH=/data/bin/app_log
echo "################################# 合成APP LOG文件 #################################"
# 创建app log临时文件夹
if [ -d ${APP_LOG_TMP_PATH} ]; then
echo "rm -rf ${APP_LOG_TMP_PATH}"
rm -rf ${APP_LOG_TMP_PATH}
fi
echo "create app_tmp_dir"
mkdir -p ${APP_LOG_TMP_PATH}
# 拉取app log文件
echo "pull robot ${ROBOT_APP_LOG_PATH}"
sshpass -p 1 rsync -avz --progress root@${ROBOT_IP}:${ROBOT_APP_LOG_PATH}/*.log ${APP_LOG_TMP_PATH}
# 获取LOG文件最后一次修改的时间戳
APP_LOG_FILE_LIST=($(ls ${APP_LOG_TMP_PATH}/*.log))
for i in "${!APP_LOG_FILE_LIST[@]}";
do
APP_LOG_FILE="${APP_LOG_TMP_PATH}/${i}.log"
# echo ${APP_LOG_FILE}
# echo "i = "${i}
APP_LOG_FILE_TIME_ARR[${i}]=$(stat -c %Y ${APP_LOG_FILE})
APP_LOG_FILE_DATE_ARR[${i}]=$(date '+%Y-%m-%d %H:%M:%S' -d @${APP_LOG_FILE_TIME_ARR[${i}]})
echo ${APP_LOG_FILE} ${APP_LOG_FILE_DATE_ARR[${i}]} ${APP_LOG_FILE_TIME_ARR[${i}]}
APP_LOG_FILE_TIME_SORT_ARR[${i}]=${APP_LOG_FILE_TIME_ARR[${i}]}
# echo ${APP_LOG_FILE_TIME_SORT_ARR[${i}]}
done
# 时间戳从小到大排序
for((i = 0; i < ${#APP_LOG_FILE_TIME_SORT_ARR[@]}; i++))
{
for((j = 0; j < ${#APP_LOG_FILE_TIME_SORT_ARR[@]} - 1; j++))
{
if [[ ${APP_LOG_FILE_TIME_SORT_ARR[j]} -gt ${APP_LOG_FILE_TIME_SORT_ARR[j+1]} ]]; then
tmp=${APP_LOG_FILE_TIME_SORT_ARR[j]}
APP_LOG_FILE_TIME_SORT_ARR[j]=${APP_LOG_FILE_TIME_SORT_ARR[j+1]}
APP_LOG_FILE_TIME_SORT_ARR[j+1]=$tmp
fi
}
}
echo "app log timestamp after sort"
echo ${APP_LOG_FILE_TIME_SORT_ARR[@]}
# 记录时间戳从小到大的文件
for((sort_index = 0; sort_index < ${#APP_LOG_FILE_TIME_SORT_ARR[@]}; sort_index++))
{
for((ori_index = 0; ori_index < ${#APP_LOG_FILE_TIME_ARR[@]}; ori_index++))
{
# echo ${ori_index}
if [ ${APP_LOG_FILE_TIME_SORT_ARR[${sort_index}]} = ${APP_LOG_FILE_TIME_ARR[${ori_index}]} ]; then
APP_LOG_INDEX_ARR[${sort_index}]=${ori_index}
fi
}
}
echo "APP_LOG_INDEX_ARR=${APP_LOG_INDEX_ARR[@]} len=${#APP_LOG_INDEX_ARR[@]}"
# 总app log文件合成
if [ ${#APP_LOG_INDEX_ARR[@]} -le 0 ]; then
echo "app log merge error!!"
else
touch ${APP_MERGE_LOG_FILE}
for i in ${!APP_LOG_INDEX_ARR[@]};
do
$(cat ${APP_LOG_TMP_PATH}/${APP_LOG_INDEX_ARR[${i}]}.log >> ${APP_MERGE_LOG_FILE} 2>&1)
done
echo "merge app_log success!! file_name: ${APP_MERGE_LOG_FILE}"
fi
# 删除app log临时文件
echo "clean tmp app log file"
rm -rf ${APP_LOG_TMP_PATH}
机器上的app的log循环存储若干份,要看完整log需要自己从机器上拷贝各log文件,并进行合并。
其中,有用到一个rsync远程同步工具,可参考往期文章:本地与远程设备之间如何有效地进行文件同步?
3、一键更新程序
#! /bin/bash
#####################################################################
# 脚本功能:一键更新程序
#####################################################################
# 1、使用wifi更新,输入命令:./push_all_pros.sh wifi
# 2、使用adb更新,输入命令:./push_all_pros.sh adb
# 机器IP
ROBOT_IP=172.13.10.36
# 源路径(PC路径)
AI_SO_LIB_SRC_PATH=./AI/data/lib
AI_CONFIG_SRC_PATH=./AI/data/config
AI_MODEL_SRC_PATH=./AI/data/model
AI_EXE_FILE_SRC_PATH=./AI/data/bin
APP_EXE_FILE_SRC_PATH=./app
# 目标路径(机器路径)
AI_SO_LIB_TARTET_PATH=/data/lib
AI_CONFIG_TARGET_PATH=/data/config
AI_MODEL_TARGET_PATH=/data/model
AI_EXE_FILE_TARGET_PATH=/data/bin
APP_EXE_FILE_TARGET_PATH=/data/bin
# 程序名称
AI_EXE_NAME=ai
APP_EXE_NAME=app
# adb传输
if [ $1 = "adb" ]; then
# 更新AI lib files
echo "========== AI_SO_FILE =========="
SO_LIST=($(ls ${AI_SO_LIB_SRC_PATH}/*.so))
for i in "${!SO_LIST[@]}";
do
SO_NAME=${SO_LIST[$i]}
echo "push ${SO_NAME} ${AI_SO_LIB_TARTET_PATH} ..."
adb push ${SO_NAME} ${AI_SO_LIB_TARTET_PATH}
done
echo -e "\n"
# 更新AI cfg files
echo "========== AI_INI_FILE =========="
INI_LIST=($(ls ${AI_CONFIG_SRC_PATH}/*.ini))
for i in "${!INI_LIST[@]}"
do
INI_NAME=${INI_LIST[$i]}
echo "push ${INI_NAME} ${AI_CONFIG_TARGET_PATH} ..."
adb push ${INI_NAME} ${AI_CONFIG_TARGET_PATH}
done
echo -e "\n"
# 更新AI model files
echo "========== AI_MODLE_FILE =========="
MODEL_LIST=($(ls ${AI_MODEL_SRC_PATH}/*.rknn))
for i in "${!MODEL_LIST[@]}"
do
MODEL_NAME=${MODEL_LIST[$i]}
echo "push ${MODEL_NAME} ${AI_MODEL_SRC_PATH} ..."
adb push ${MODEL_NAME} ${AI_MODEL_TARGET_PATH}
done
echo -e "\n"
# 更新AI pro
echo "========== AI_EXE_FILE =========="
echo "push ${AI_EXE_FILE_SRC_PATH}/${AI_EXE_NAME} ${AI_EXE_FILE_TARGET_PATH} ..."
adb push ${AI_EXE_FILE_SRC_PATH}/${AI_EXE_NAME} ${AI_EXE_FILE_TARGET_PATH}
echo -e "\n"
# 更新app pro
echo "========== APP_EXE_FILE =========="
echo "push ${APP_EXE_FILE_SRC_PATH}/${APP_EXE_NAME} ${APP_EXE_FILE_TARGET_PATH} ..."
adb push ${APP_EXE_FILE_SRC_PATH}/${APP_EXE_NAME} ${APP_EXE_FILE_TARGET_PATH}
# wifi传输
elif [ $1 = "wifi" ]; then
echo "========== AI_EXE_FILE =========="
echo "push ${AI_EXE_FILE_SRC_PATH}/${AI_EXE_NAME} ${AI_EXE_FILE_TARGET_PATH} ..."
sshpass -p 1 scp ${AI_SO_LIB_SRC_PATH}/*.so root@${ROBOT_IP}:${AI_SO_LIB_TARTET_PATH}
sshpass -p 1 scp ${AI_CONFIG_SRC_PATH}/*.ini root@${ROBOT_IP}:${AI_CONFIG_TARGET_PATH}
sshpass -p 1 scp ${AI_MODEL_SRC_PATH}/*.rknn root@${ROBOT_IP}:${AI_MODEL_TARGET_PATH}
sshpass -p 1 scp ${AI_EXE_FILE_SRC_PATH}/${AI_EXE_NAME} root@${ROBOT_IP}:${AI_EXE_FILE_TARGET_PATH}
echo "========== APP_EXE_FILE =========="
echo "push ${APP_EXE_FILE_SRC_PATH}/${APP_EXE_NAME} ${APP_EXE_FILE_TARGET_PATH} ..."
sshpass -p 1 scp ${APP_EXE_FILE_SRC_PATH}/${APP_EXE_NAME} root@${ROBOT_IP}:${APP_EXE_FILE_TARGET_PATH}
echo -e "push all pro end!"
fi
每次发布版本,都需要更新好多文件,一个一个传有些繁琐,故写了一个一键更新脚本。可使用无线更新,也可以使用有线更新。
4、一键运行程序
#!/bin/bash
#####################################################################
# 脚本功能:一键运行所有程序
#####################################################################
# 脚本log名称
APP_SCRIPT_RUN_LOG=app_script_log
# 每次启动都先把脚本的log给删掉
if [ -f ${APP_SCRIPT_RUN_LOG} ]; then
rm -f ${APP_SCRIPT_RUN_LOG}
fi
# 输入命令
if [ $# != 2 ] ; then
echo "Usage: $0 app_pro ai_pro"
exit 1;
fi
# 程序路径
PROGRAM_PATH=/data/bin
# 程序名称
APP_EXE_NAME=${PROGRAM_PATH}/$1
AI_EXE_NAME=${PROGRAM_PATH}/$2
# 运行程序之前先清除log等数据
delete_script=delete_data.sh
if [ -f ${delete_script} ]; then
echo "delete data..."
source ${delete_script}
else
echo "${delete_script} not exit!!!"
fi
# 启动http服务
thttpd -D -C /etc/thttpd.conf &
# 后台运行程序
nohup ${APP_EXE_NAME} &
app_run_result=$(ps -ef | grep -w ${APP_EXE_NAME} | grep -v grep | wc -l)
if [ ${app_run_result} -eq 1 ]; then
echo "app_run_result = ${app_run_result}, ${APP_EXE_NAME} run success!!" >> ${APP_SCRIPT_RUN_LOG}
else
echo "app_run_result = ${app_run_result}, ${APP_EXE_NAME} run error!!" >> ${APP_SCRIPT_RUN_LOG}
fi
nohup ${AI_EXE_NAME} &
ai_run_result=$(ps -ef | grep -w ${AI_EXE_NAME} | grep -v grep | wc -l)
if [ ${ai_run_result} -eq 1 ]; then
echo "ai_run_result = ${ai_run_result}, ${AI_EXE_NAME} run success!!" >> ${APP_SCRIPT_RUN_LOG}
else
echo "ai_run_result = ${ai_run_result}, ${AI_EXE_NAME} run error!!" >> ${APP_SCRIPT_RUN_LOG}
fi
# 程序重复运行了,杀死所有进程,重新执行脚本
if [ ${app_run_result} -gt 1 -o ${ai_run_result} -gt 1 ]; then
killall_script=killall_pro.sh
if [ -f ${killall_script} ]; then
echo "kill all app pros..."
source ${killall_script}
else
echo "${killall_script} not exit!!!"
fi
sleep 1
source run_all_pros.sh
fi
平时开发过程中,有时候会挂着几个终端运行几个程序,有时候也需要一键后台运行所有程序。上面脚本可一键运行所有程序于后台,稍作修改可设置成开机自启动。
开机自启动相关内容可查看往期文章:干货 | 浅析程序开机自启动
5、一键杀死进程
#!/bin/bash
#####################################################################
# 脚本功能:一键杀死进程
#####################################################################
RELEASE_APP_NAME=app
RELEASE_AI_NAME=ai
release_app_run_result=$(ps -ef | grep ${RELEASE_APP_NAME} | grep -v grep | wc -l)
if [ ${release_app_run_result} -gt 0 ]; then
killall -9 ${RELEASE_APP_NAME}*
echo "kill ${RELEASE_APP_NAME}* success!!"
fi
release_ai_run_result=$(ps -ef | grep ${RELEASE_AI_NAME} | grep -v grep | wc -l)
if [ ${release_ai_run_result} -gt 0 ]; then
killall -9 ${RELEASE_AI_NAME}*
echo "kill ${RELEASE_AI_NAME}* success!!"
fi
http_run_result=$(ps -ef | grep -w thttpd | grep -v grep | wc -l)
if [ ${http_run_result} -gt 0 ]; then
killall -9 thttpd
echo "kill thttpd success!!"
fi
与上面的一键运行脚本相对应,一键杀死所有进程。
以上就是本次的分享~