常用脚本和配置 服务器

2025-04-26 约 3418 字 阅读时长7 分钟

常用脚本和配置

笔记自动更新部署

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 30

t_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.target
bash
 1# 开机自启服务
 2systemctl enable myscript
 3
 4# 关闭开机自启
 5systemctl disable myscript
 6
 7# 启动服务
 8systemctl start myscript
 9
10# 关闭服务
11systemctl stop myscript
12
13# 查看服务状态
14systemctl status myscript.service

winStartNote

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
8pause

sh脚本

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}
124main

java程序启动脚本

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
使用滚轮缩放
按住拖动