服务器应用操作命令

帕鲁更新命令

执行以下命令对 Ubuntu 服务器中的帕鲁游戏进行自动更新:

# 从指定 URL 下载并执行更新脚本
wget -O - https://pal.pet/pal-server/Ubuntu/update.sh | sh

FRP 端口映射

  1. 分别在服务端和客户端分别下载并解压 frp,然后进入解压后的目录:

    # 下载 FRP 压缩包
    wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
    # 解压 FRP 压缩包
    tar -zxvf frp_0.61.1_linux_amd64.tar.gz
    # 进入解压后的目录
    cd frp_0.61.1_linux_amd64
    
  2. 配置服务端
    在服务端上进行如下配置:

    • 配置服务端配置文件:

      bindPort = 7000  # 设置 FRP 服务端口,确保该端口未被占用
      auth.token = "xxxx"  # 设置 Token,用于客户端和服务端的认证
      webServer.addr = "0.0.0.0"      # 设置 Web 后台监听地址,0.0.0.0 表示监听所有网络接口
      webServer.port = 7500           # 设置 Web 后台监听端口
      webServer.user = "admin"         # 设置 Web 后台登录用户名
      webServer.password = "123456"  # 设置 Web 后台登录密码
      

      全部服务端配置请参考:https://github.com/fatedier/frp/blob/dev/conf/frps_full_example.toml

    • 启动/重启脚本:
      创建脚本:

      # 创建 start_frps.sh 脚本
      vim start_frps.sh
      

      脚本内容:

      点击查看代码
      #!/bin/bash
      # 获取脚本所在目录
      SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
      # 设置 frps 可执行文件路径
      frps_BIN="$SCRIPT_DIR/frps"
      frps_CONFIG="$SCRIPT_DIR/frps.toml"   # 配置文件路径
      LOG_FILE="$SCRIPT_DIR/frps.log"       # 日志文件路径
      # 获取 frps 进程 ID
      get_frps_pid() {
      	pgrep -f "$frps_BIN" 2>/dev/null   # 查找 frps 进程 ID
      }
      # 停止 frps 进程
      stop_frps() {
      	local pid=$(get_frps_pid)   # 获取 frps 进程 ID
      	if [[ -n "$pid" ]]; then
      		echo "Stopping frps (PID: $pid)..."   # 停止 frps
      		kill "$pid" 2>/dev/null   # 终止 frps 进程
      		sleep 2   # 等待进程停止
      		kill -9 "$pid" 2>/dev/null  # 强制停止进程(如果没有成功停止)
      	else
      		echo "frps is not running."   # 如果没有找到 frps 进程
      	fi
      }
      # 启动 frps 进程
      start_frps() {
      	echo "Starting frps..."   # 输出启动信息
      	nohup "$frps_BIN" -c "$frps_CONFIG" > "$LOG_FILE" 2>&1 &   # 后台启动 frps 并记录日志
      	# 检查 frps 是否成功启动
      	sleep 2   # 等待一段时间
      	local new_pid=$(get_frps_pid)   # 获取新的进程 ID
      	if [[ -n "$new_pid" ]]; then
      		echo "frps started (PID: $new_pid)"   # 输出启动成功信息
      	else
      		echo "frps failed to start."   # 启动失败,输出失败信息
      		exit 1   # 退出脚本
      	fi
      }
      # 停止并重新启动 frps
      stop_frps
      start_frps
      

      脚本设置可执行权限:

      # 给 start_frps.sh 设置可执行权限
      chmod +x start_frps.sh   
      
  3. 配置客户端

    • 配置客户端配置文件:

      serverAddr = "x.x.x.x"  # 设置 FRP 服务器地址
      serverPort = 7000       # 设置 FRP 服务端口
      
      [[proxies]]
      name = "test-tcp"       # 隧道名称,客户端可以自定义
      type = "tcp"            # 使用 TCP 协议
      localIP = "127.0.0.1"   # 本地地址
      localPort = 22          # 本地端口
      remotePort = 6000       # 远程端口
      

      全部客户端配置请参考:https://github.com/fatedier/frp/blob/dev/conf/frpc_full_example.toml

    • 启动/重启脚本:

      创建脚本:

      # 创建 start_frpc.sh 脚本
      vim start_frpc.sh
      

      脚本内容:

      点击查看代码
      #!/bin/bash
      
      # 获取脚本所在目录
      SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
      
      # 设置 frpc 可执行文件路径
      frpc_BIN="$SCRIPT_DIR/frpc"
      frpc_CONFIG="$SCRIPT_DIR/frpc.toml"   # 配置文件路径
      LOG_FILE="$SCRIPT_DIR/frpc.log"       # 日志文件路径
      
      # 获取 frpc 进程 ID
      get_frpc_pid() {
      	pgrep -f "$frpc_BIN" 2>/dev/null   # 查找 frpc 进程 ID
      }
      
      # 停止 frpc 进程
      stop_frpc() {
      	local pid=$(get_frpc_pid)   # 获取 frpc 进程 ID
      	if [[ -n "$pid" ]]; then
      		echo "Stopping frpc (PID: $pid)..."   # 停止 frpc
      		kill "$pid" 2>/dev/null   # 终止 frpc 进程
      		sleep 2   # 等待进程停止
      		kill -9 "$pid" 2>/dev/null  # 强制停止进程(如果没有成功停止)
      	else
      		echo "frpc is not running."   # 如果没有找到 frpc 进程
      	fi
      }
      
      # 启动 frpc 进程
      start_frpc() {
      	echo "Starting frpc..."   # 输出启动信息
      	nohup "$frpc_BIN" -c "$frpc_CONFIG" > "$LOG_FILE" 2>&1 &   # 后台启动 frpc 并记录日志
      
      	# 检查 frpc 是否成功启动
      	sleep 2   # 等待一段时间
      	local new_pid=$(get_frpc_pid)   # 获取新的进程 ID
      	if [[ -n "$new_pid" ]]; then
      		echo "frpc started (PID: $new_pid)"   # 输出启动成功信息
      	else
      		echo "frpc failed to start."   # 启动失败,输出失败信息
      		exit 1   # 退出脚本
      	fi
      }
      
      # 停止并重新启动 frpc
      stop_frpc
      start_frpc
      

      脚本设置可执行权限:

      # 给 start_frpc.sh 设置可执行权限
      chmod +x start_frpc.sh   
      

根据CPU和GPU温度调整风扇转速

这段脚本的作用是根据 GPU 和 CPU 的温度自动调整计算机风扇的转速,以确保系统保持在合适的温度范围内,避免过热:

  1. 创建脚本文件,在服务器上创建一个目录来存放脚本,例如 /data/fan_control/,然后在这个目录下创建脚本文件 fan_control.sh

    点击查看代码
    #!/bin/bash
    
    # 获取脚本所在目录
    script_dir=$(dirname "$0")
    log_file="$script_dir/ipmi.log"
    current_time=$(date "+%Y-%m-%d %H:%M")
    max_temperature_gpu=0
    max_temperature_cpu=0
    sleep_interval=5  # 设置为5秒,可以根据实际需要进行调整
    last_speed=0  # 初始化last_speed为0
    
    # 创建日志文件(如果不存在)
    if [[ ! -f "$log_file" ]]; then
    	touch "$log_file"
    fi
    
    # 禁用自动风扇调节 (设置风扇控制为手动)
    ipmitool raw 0x30 0x30 0x01 0x00 && echo "$current_time - 禁用自动风扇调节,设置为手动控制" >> "$log_file"
    
    # 获取最高的GPU温度
    get_max_temperature_gpu() {
    	max_temperature_gpu=0
    	# 使用nvidia-smi获取GPU温度
    	local gpu_temps=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits 2>/dev/null)
    	if [[ -z "$gpu_temps" ]]; then
    		echo "$current_time - 无法检测到GPU温度" >> "$log_file"
    		return
    	fi
    	for temp in $gpu_temps; do
    		# 检查是否为有效浮点数
    		temp=$(echo "$temp" | sed 's/[^0-9.]//g')  # 清除非数字字符
    		if [[ "$temp" =~ ^[0-9]+([.][0-9]+)?$ ]] && (( $(echo "$temp > $max_temperature_gpu" | bc -l) )); then
    			max_temperature_gpu=$temp
    		fi
    	done
    	if (( $(echo "$max_temperature_gpu == 0" | bc -l) )); then
    		echo "$current_time - 检测到GPU温度但未能解析有效数值" >> "$log_file"
    	fi
    }
    
    # 获取最高的CPU温度
    get_max_temperature_cpu() {
    	max_temperature_cpu=0
    	# 使用ipmitool sensor获取CPU温度
    	local cpu_temps=$(ipmitool sensor | grep -P '^Temp\s+\|' | awk '{print $3}')
    	if [[ -z "$cpu_temps" ]]; then
    		echo "$current_time - 无法检测到CPU温度" >> "$log_file"
    		return
    	fi
    	for temp in $cpu_temps; do
    		# 清除非数字字符,并检查是否为有效浮点数
    		temp=$(echo "$temp" | sed 's/[^0-9.]//g')  # 清除非数字字符
    		if [[ "$temp" =~ ^[0-9]+([.][0-9]+)?$ ]] && (( $(echo "$temp > $max_temperature_cpu" | bc -l) )); then
    			max_temperature_cpu=$temp
    		fi
    	done
    	if (( $(echo "$max_temperature_cpu == 0" | bc -l) )); then
    		echo "$current_time - 检测到CPU温度但未能解析有效数值" >> "$log_file"
    	fi
    }
    
    # 风扇调整函数
    adjust_fan_speed() {
    	local max_temp=$1    # 最高温度
    	local temp_gpu=$2    # GPU最高温度
    	local temp_cpu=$3    # CPU最高温度
    	local speed=30  # 默认30%
    
    	if (( $(echo "$max_temp > 55" | bc -l) && $(echo "$max_temp <= 65" | bc -l) )); then
    		speed=50  # 50%
    	elif (( $(echo "$max_temp > 65" | bc -l) && $(echo "$max_temp <= 75" | bc -l) )); then
    		speed=80  # 80%
    	elif (( $(echo "$max_temp > 75" | bc -l) )); then
    		speed=100  # 100%
    	fi
    
    	# 只有当风扇转速发生变化时,才执行调整命令
    	if [[ "$speed" -ne "$last_speed" ]]; then
    		ipmitool raw 0x30 0x30 0x02 0xff $(printf "0x%02x" $((speed)))
    		echo "$current_time - 最高温度: $max_temp°C (GPU: ${temp_gpu}°C, CPU: ${temp_cpu}°C), 风扇转速调整为 ${speed}%" >> "$log_file"
    		last_speed=$speed  # 更新last_speed
    	else
    		echo "$current_time - 风扇转速没有变化,当前温度: 最高温度 $max_temp°C (GPU: ${temp_gpu}°C, CPU: ${temp_cpu}°C)" >> "$log_file"
    	fi
    }
    
    # 循环调整风扇转速,每5秒检查一次
    while true; do
    	get_max_temperature_gpu
    	get_max_temperature_cpu
    
    	# 如果没有获取到GPU或CPU的温度,跳过调整
    	if (( $(echo "$max_temperature_gpu == 0" | bc -l) && $(echo "$max_temperature_cpu == 0" | bc -l) )); then
    		echo "$current_time - 无法获取GPU或CPU温度,跳过风扇调整" >> "$log_file"
    		sleep $sleep_interval
    		continue
    	fi
    
    	# 选择最大温度作为依据
    	if (( $(echo "$max_temperature_gpu > $max_temperature_cpu" | bc -l) )); then
    		max_temperature=$max_temperature_gpu
    	else
    		max_temperature=$max_temperature_cpu
    	fi
    
    	adjust_fan_speed $max_temperature $max_temperature_gpu $max_temperature_cpu
    	sleep $sleep_interval
    done
    
    
    
    # crontab -e
    # @reboot /bin/bash /data/fan_control/fan_control.sh
    # crontab -l
    # tail -f /data/fan_control/ipmi.log
    
  2. 给脚本文件设置可执行权限:

    chmod +x /data/fan_control/fan_control.sh
    
  3. 配置脚本开机自启动:
    编辑 crontab 配置文件:

    crontab -e
    

    在配置文件中写入:

    @reboot /bin/bash /data/fan_control/fan_control.sh
    
  4. 检查日志文件:

    tail -f /data/fan_control/ipmi.log
    

查看显存占用超过 1g 的 docker 容器信息

点击查看代码
#!/bin/bash

# 获取显存占用大于 1GB 的进程 PID 和显存占用大小
gpu_info=$(nvidia-smi --query-compute-apps=pid,used_memory,process_name --format=csv,noheader,nounits | awk -F ', ' '
{
    mem_mib = $2 + 0;
    if (mem_mib > 1024 && $3 ~ /python/) {
        print $1, mem_mib
    }
}')

if [ -z "$gpu_info" ]; then
    echo "No GPU processes with memory usage > 1GB found."
    exit 0
fi

echo "GPU Processes with Memory Usage > 1GB:"
echo "-------------------------------------"
echo "PID     GPU Memory (MiB)   Container ID      Container Name       Image"
echo "------------------------------------------------------------------------------------------"

while read -r pid gpu_memory; do
    # 通过 cgroup 查找容器 ID(兼容不同格式的 Docker/containerd 路径)
    container_id=$(cat /proc/$pid/cgroup 2>/dev/null | grep -oE '[0-9a-f]{64}' | head -n 1)
    
    # 如果未找到 64 位 ID,尝试匹配 12 位短 ID
    if [ -z "$container_id" ]; then
        container_id=$(cat /proc/$pid/cgroup 2>/dev/null | grep -oE 'docker-([0-9a-f]{64})' | head -n 1 | cut -d '-' -f2)
    fi

    # 如果仍为空,尝试通过容器运行时接口查找
    if [ -z "$container_id" ]; then
        container_id=$(docker ps -q --no-trunc | xargs docker inspect --format '{{.Id}} {{.State.Pid}}' | awk -v pid="$pid" '$2 == pid {print $1}')
    fi

    if [ -n "$container_id" ]; then
        # 截取 12 位短 ID(兼容 docker ps 输出)
        short_id=$(echo "$container_id" | cut -c1-12)
        container_info=$(docker inspect --format '{{.Name}} {{.Config.Image}}' "$container_id" 2>/dev/null)
        container_name=$(echo "$container_info" | awk '{print $1}' | sed 's|/||g')
        container_image=$(echo "$container_info" | awk '{print $2}')
        echo "$pid   $gpu_memory MiB        $short_id   $container_name   $container_image"
    else
        echo "$pid   $gpu_memory MiB        Not a Docker container process"
    fi
done <<< "$gpu_info"

echo "------------------------------------------------------------------------------------------"
posted @ 2025-02-09 14:59  gokamisama  阅读(36)  评论(0)    收藏  举报