常用脚本和配置 ¶
笔记自动更新部署 ¶
autorun ¶
autorun.sh
shell
1#!/bin/bash
2
3# 设置环境变量
4export PATH=/opt/mime/soft/hugo_extended_0.139.2:/opt/mime/soft/nginx/sbin:$PATH
5export NVM_DIR="/opt/mime/soft/nvm"
6[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
7[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
8
9# 检测网络环境,无外网睡眠3秒继续执行
10while !(ping -c 4 8.8.8.8 &> /dev/null;) do
11 echo "网络连接失败,等待3秒下次检测"
12 sleep 3
13done
14
15echo "网络连接正常。"
16
17# 启动nginx
18nginx
19
20# ddns
21nohup /opt/mime/py/venv/bin/python -u /opt/mime/py/t_ddns.py > /opt/mime/py/log/t_ddns.log 2>&1 &
22# 自动检测note git仓库,并更新和构建
23nohup sh /opt/mime/script/autoUpdateNote.sh > /opt/mime/py/log/autoUpdateNote.log 2>&1 &autoUpdateNote ¶
autoUpdateNote.sh
shell
1#!/bin/sh
2
3# 项目目录
4path="/opt/mime/git/note_hugo"
5
6# 定时更新git项目、并打印结果
7pull_git() {
8 echo "$(date +"%Y-%m-%d %H:%M:%S"): 开始更新程序"
9
10 # 更新git库
11 res=$(git -C "$path" pull 2>&1)
12
13 echo "当前操作系统: $(uname)"
14 echo "更新结果: $res" # 标准输出
15
16
17
18 # 更新程序
19 case "$res" in
20 *"Already up to date"*)
21 echo "Already up to date."
22 ;;
23 *"Updating"*)
24 cd "$path/themes/hugo-tl" || { echo "无法切换到目录: $path/themes/hugo-tl"; exit 1; }
25 res=$(yarn install 2>&1)
26 echo "yarn install result: $res"
27 res=$(yarn run build 2>&1)
28 echo "yarn run build result: $res"
29 ;;
30 *)
31 echo "update failed."
32 ;;
33 esac
34}
35
36# 开始执行程序,每隔30秒执行一次
37while true; do
38 pull_git
39 echo "$(date +"%Y-%m-%d %H:%M:%S"): 更新程序结束, 休眠中..."
40 sleep 30t_ddns ¶
t_ddns.py
python
1import json
2import time
3import socket
4from tencentcloud.common import credential
5from tencentcloud.common.profile.client_profile import ClientProfile
6from tencentcloud.common.profile.http_profile import HttpProfile
7from tencentcloud.common.exception.tencent_cloud_sdk_exception import (
8 TencentCloudSDKException,
9)
10from tencentcloud.dnspod.v20210323 import dnspod_client, models
11
12# 安装依赖 pip install -i https://mirrors.tencent.com/pypi/simple/ --upgrade tencentcloud-sdk-python
13
14
15# 获取本地 IPv6 地址
16def get_local_ipv6():
17 try:
18 s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
19 s.connect(
20 ("2001:4860:4860::8888", 80)
21 ) # 使用一个公共的IPv6地址(这里是谷歌的DNS服务器IPv6地址)
22 local_ipv6 = s.getsockname()[0]
23 s.close()
24 return local_ipv6
25 except Exception as e:
26 print(f"获取本机IPv6地址时出错: {e}")
27 return None
28
29
30# 更新 IPv6 地址到 DNSPod
31def update_dns_ipv6(cred, dictInfo):
32 try:
33 # 实例化一个http选项,可选的,没有特殊需求可以跳过
34 httpProfile = HttpProfile()
35 httpProfile.endpoint = "dnspod.tencentcloudapi.com"
36
37 # 实例化一个client选项,可选的,没有特殊需求可以跳过
38 clientProfile = ClientProfile()
39 clientProfile.httpProfile = httpProfile
40 # 实例化要请求产品的client对象,clientProfile是可选的
41 client = dnspod_client.DnspodClient(cred, "", clientProfile)
42
43 # 实例化一个请求对象,每个接口都会对应一个request对象
44 req = models.ModifyRecordRequest()
45 params = {
46 "Domain": dictInfo.get("Domain"),
47 "RecordType": dictInfo.get("RecordType", "AAAA"),
48 "RecordLine": dictInfo.get("RecordLine", "默认"),
49 "Value": dictInfo.get("Value"),
50 "RecordId": dictInfo.get("RecordId"),
51 "SubDomain": dictInfo.get("SubDomain"),
52 }
53 req.from_json_string(json.dumps(params))
54
55 # 返回的resp是一个ModifyRecordResponse的实例,与请求对象对应
56 resp = client.ModifyRecord(req)
57 # 输出json格式的字符串回包
58 print(resp.to_json_string())
59 except TencentCloudSDKException as err:
60 print(err)
61
62
63# 获取远端现有记录,域名、子域名名称
64def get_one_record(cred, dictInfo):
65 try:
66 # 实例化一个http选项,可选的,没有特殊需求可以跳过
67 httpProfile = HttpProfile()
68 httpProfile.endpoint = "dnspod.tencentcloudapi.com"
69
70 # 实例化一个client选项,可选的,没有特殊需求可以跳过
71 clientProfile = ClientProfile()
72 clientProfile.httpProfile = httpProfile
73 # 实例化要请求产品的client对象,clientProfile是可选的
74 client = dnspod_client.DnspodClient(cred, "", clientProfile)
75
76 # 实例化一个请求对象,每个接口都会对应一个request对象
77 req = models.DescribeRecordListRequest()
78 params = {"Domain": dictInfo.get("Domain")}
79 req.from_json_string(json.dumps(params))
80 # 返回的resp是一个DescribeRecordListResponse的实例,与请求对象对应
81 resp = client.DescribeRecordList(req)
82 for record in resp.RecordList:
83 if record.Name == dictInfo.get("SubDomain", "-----"):
84 return record
85 # 输出json格式的字符串回包
86 return None
87 except TencentCloudSDKException as err:
88 print(err)
89
90
91if __name__ == "__main__":
92
93 domain = "leilife.site"
94 subDomain = "note"
95
96 secretId = "****************************"
97 secretKey = "********************************"
98 # 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
99 cred = credential.Credential(secretId, secretKey)
100 print(
101 time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())),
102 ": 开始执行ddns",
103 )
104 # 单挑解析记录
105 record = get_one_record(cred, {"Domain": domain, "SubDomain": subDomain})
106
107 while True:
108 # 获取dns记录解析的ip地址
109 remoteIp = record.Value
110 # 获取本地ip地址
111 localIp = get_local_ipv6()
112 print("本地ip地址: ", localIp)
113 print("dns记录解析ip地址: ", remoteIp)
114 if remoteIp != localIp and localIp is not None:
115 print("ip地址不一致,需要更新")
116 update_dns_ipv6(
117 cred, {"Domain": domain, "SubDomain": subDomain, "Value": localIp,"RecordId":record.RecordId}
118 )
119 elif localIp is None:
120 print("本地ip地址获取失败,稍后重试")
121 else:
122 print("ip地址一致,不需要更新")
123
124 print(
125 time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())),
126 ": 更新ddns结束, 休眠中...\n\n",
127 )
128 time.sleep(60 * 30) # 每隔30分钟执行一次开机自启 ¶
/etc/systemd/system/ 目录下新建服务 myscript.service
1[Unit]
2Description=My Startup Script
3After=network.target
4
5[Service]
6Type=forking
7ExecStart=/opt/mime/script/autorun.sh
8
9[Install]
10WantedBy=multi-user.targetbash
1# 开机自启服务
2systemctl enable myscript
3
4# 关闭开机自启
5systemctl disable myscript
6
7# 启动服务
8systemctl start myscript
9
10# 关闭服务
11systemctl stop myscript
12
13# 查看服务状态
14systemctl status myscript.servicewinStartNote ¶
startNote.bat
bat
1@echo off
2SET targetDir=F:\study\git\note_hugo
3cd /d %targetDir%
4git pull
5SET targetDir=F:\study\git\note_hugo\themes\hugo-tl
6cd /d %targetDir%
7npm run dev
8pausesh脚本 ¶
python程序启动脚本 ¶
bash
1#!/bin/bash
2#--------------------------------------------------------
3# Author :tanglei
4# Description :python程序启动脚本
5#--------------------------------------------------------
6
7# 脚本所在目录,$0为脚本文件路径,dirname提取目录部分
8SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
9LOG_DIR="$SCRIPT_DIR/log" # 日志目录
10APP_LOG="$LOG_DIR/app.log" # 应用日志
11OPERATE_LOG="$LOG_DIR/operate.log" # 操作日志
12
13cd "$SCRIPT_DIR"
14
15if [ ! -d "$LOG_DIR" ]; then
16 mkdir -p "$LOG_DIR"
17fi
18
19# -------------- 环境变量 ------------------
20export PATH=$PATH:"$SCRIPT_DIR/.runtime/bin"
21# -----------------------------------------
22
23# -------------- 配置 ------------------
24PIDFILE=".pid" # PID文件
25APP_FILE="main.py" # 脚本名,建议使用特定的名称,如 face_main.py
26# --------------------------------
27
28start() {
29 if [[ -f "$PIDFILE" ]]; then
30 PID=$(cat "$PIDFILE")
31 if kill -0 "$PID"; then
32 echo "$APP_FILE程序已在运行,PID=$PID" | tee -a "$OPERATE_LOG"
33 return 1
34 fi
35 echo "删除旧的PID文件 $PIDFILE" | tee -a "$OPERATE_LOG"
36 rm -f "$PIDFILE"
37 fi
38 echo "正在启动 $APP_FILE ..." | tee -a "$OPERATE_LOG"
39
40 nohup python $APP_FILE > "$APP_LOG" 2>&1 &
41 echo $! > "$PIDFILE"
42
43 # 等待三秒,判断是否启动成功
44 sleep 3
45 if [[ -f "$PIDFILE" ]]; then
46 PID=$(cat "$PIDFILE")
47 if kill -0 "$PID"; then
48 echo "$APP_FILE程序启动成功,PID=$PID" | tee -a "$OPERATE_LOG"
49 return 0
50 fi
51 fi
52 echo "$APP_FILE程序启动失败" | tee -a "$OPERATE_LOG"
53 return 1
54
55}
56
57clear_log() {
58 echo "正在清除日志..." | tee -a "$OPERATE_LOG"
59 > "$APP_LOG"
60 echo "日志清除完成" | tee -a "$OPERATE_LOG"
61}
62
63stop() {
64 if [[ ! -f "$PIDFILE" ]]; then
65 echo "找不到 pidfile,程序可能未启动" | tee -a "$OPERATE_LOG_FILE"
66 return 1
67 fi
68 PID=$(cat "$PIDFILE")
69 if kill -0 "$PID" 2>/dev/null; then
70 echo "正在停止 $APP_FILE ..." | tee -a "$OPERATE_LOG"
71 kill -9 "$PID"
72 while kill -0 "$PID" 2>/dev/null; do
73 sleep 1
74 done
75 rm -f "$PIDFILE"
76 echo "$APP_FILE程序停止成功,PID=$PID" | tee -a "$OPERATE_LOG"
77 return 0
78 else
79 echo "PID=$PID 不存在,可能已停止" | tee -a "$OPERATE_LOG"
80 return 1
81 fi
82}
83
84tail_log() {
85 echo "查看 $APP_FILE 日志..." | tee -a "$OPERATE_LOG"
86 tail -500f "$APP_LOG"
87 return 0
88}
89
90status() {
91 if [[ -f "$PIDFILE" ]]; then
92 PID=$(cat "$PIDFILE")
93 if kill -0 "$PID" 2>/dev/null; then
94 echo "$APP_FILE程序正在运行,PID=$PID" | tee -a "$OPERATE_LOG"
95 else
96 echo "进程 $PID 已退出,但 pidfile 仍存在" | tee -a "$OPERATE_LOG"
97 fi
98 else
99 echo "$APP_FILE程序未运行" | tee -a "$OPERATE_LOG"
100 fi
101 return 0
102}
103
104main() {
105 echo "------------------------------------------------" | tee -a "$OPERATE_LOG"
106 echo "Script executed at: $(date)" | tee -a "$OPERATE_LOG"
107 echo "------------------------------------------------"
108 echo "1. start server"
109 echo "2. stop server"
110 echo "3. status"
111 echo "4. tail log"
112 echo "5. clear log"
113 echo "------------------------------------------------"
114 read -p "please choose: " choice
115 case $choice in
116 1) start ;;
117 2) stop ;;
118 3) status ;;
119 4) tail_log ;;
120 5) clear_log ;;
121 *) exit 0 ;;
122 esac
123}
124mainjava程序启动脚本 ¶
bash
1#!/bin/bash
2#--------------------------------------------------------
3# Author :tanglei
4# Description :java程序启动脚本
5#--------------------------------------------------------
6
7# 脚本所在目录,$0为脚本文件路径,dirname提取目录部分
8SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
9LOG_DIR="$SCRIPT_DIR/log" # 日志目录
10APP_LOG="$LOG_DIR/app.log" # 应用日志
11OPERATE_LOG="$LOG_DIR/operate.log" # 操作日志
12
13cd "$SCRIPT_DIR"
14
15if [ ! -d "$LOG_DIR" ]; then
16 mkdir -p "$LOG_DIR"
17fi
18
19# -------------- 环境变量 ------------------
20# export PATH=$PATH:/data/enviroment/jdk1.8.0_461/bin
21# -----------------------------------------
22
23# -------------- 配置 ------------------
24PIDFILE=".pid" # PID文件
25APP_FILE="app.jar" # 应用jar包
26JAVA_OPTS="-Xms256m -Xmx512m" # JVM参数
27JAR_OPTS="--server.port=8000" # 应用参数
28# --------------------------------
29
30start() {
31 if [[ -f "$PIDFILE" ]]; then
32 PID=$(cat "$PIDFILE")
33 if kill -0 "$PID"; then
34 echo "$APP_FILE程序已在运行,PID=$PID" | tee -a "$OPERATE_LOG"
35 return 1
36 fi
37 echo "删除旧的PID文件 $PIDFILE" | tee -a "$OPERATE_LOG"
38 rm -f "$PIDFILE"
39 fi
40 echo "正在启动 $JAR_FILE ..." | tee -a "$OPERATE_LOG"
41
42 nohup java $JAVA_OPTS -jar $APP_FILE $JAR_OPTS > "$APP_LOG" 2>&1 &
43 echo $! > "$PIDFILE"
44
45 # 等待三秒,判断是否启动成功
46 sleep 3
47 if [[ -f "$PIDFILE" ]]; then
48 PID=$(cat "$PIDFILE")
49 if kill -0 "$PID"; then
50 echo "$APP_FILE程序启动成功,PID=$PID" | tee -a "$OPERATE_LOG"
51 return 0
52 fi
53 fi
54 echo "$APP_FILE程序启动失败" | tee -a "$OPERATE_LOG"
55 return 1
56
57}
58
59clear_log() {
60 echo "正在清除日志..." | tee -a "$OPERATE_LOG"
61 > "$APP_LOG"
62 echo "日志清除完成" | tee -a "$OPERATE_LOG"
63}
64
65stop() {
66 if [[ ! -f "$PIDFILE" ]]; then
67 echo "找不到 pidfile,程序可能未启动" | tee -a "$OPERATE_LOG_FILE"
68 return 1
69 fi
70 PID=$(cat "$PIDFILE")
71 if kill -0 "$PID" 2>/dev/null; then
72 echo "正在停止 $APP_FILE ..." | tee -a "$OPERATE_LOG"
73 kill -9 "$PID"
74 while kill -0 "$PID" 2>/dev/null; do
75 sleep 1
76 done
77 rm -f "$PIDFILE"
78 echo "$APP_FILE程序停止成功,PID=$PID" | tee -a "$OPERATE_LOG"
79 return 0
80 else
81 echo "PID=$PID 不存在,可能已停止" | tee -a "$OPERATE_LOG"
82 return 1
83 fi
84}
85
86tail_log() {
87 echo "查看 $APP_FILE 日志..." | tee -a "$OPERATE_LOG"
88 tail -500f "$APP_LOG"
89 return 0
90}
91
92status() {
93 if [[ -f "$PIDFILE" ]]; then
94 PID=$(cat "$PIDFILE")
95 if kill -0 "$PID" 2>/dev/null; then
96 echo "$APP_FILE程序正在运行,PID=$PID" | tee -a "$OPERATE_LOG"
97 else
98 echo "进程 $PID 已退出,但 pidfile 仍存在" | tee -a "$OPERATE_LOG"
99 fi
100 else
101 echo "$APP_FILE程序未运行" | tee -a "$OPERATE_LOG"
102 fi
103 return 0
104}
105
106main() {
107 echo "------------------------------------------------" | tee -a "$OPERATE_LOG"
108 echo "Script executed at: $(date)" | tee -a "$OPERATE_LOG"
109 echo "------------------------------------------------"
110 echo "1. start server"
111 echo "2. stop server"
112 echo "3. status"
113 echo "4. tail log"
114 echo "5. clear log"
115 echo "------------------------------------------------"
116 read -p "please choose: " choice
117 case $choice in
118 1) start ;;
119 2) stop ;;
120 3) status ;;
121 4) tail_log ;;
122 5) clear_log ;;
123 *) exit 0 ;;
124 esac
125}
126main