如何在运行时向程序传递参数?无需停止脚本修改API请求参数
可行解决方案
1. 原子文件替换读取
直接读写文件的核心风险是修改时可能出现“部分写入”,导致脚本读到不完整参数。用原子替换可彻底规避这个问题:
- 修改变量时,先将完整的新参数写入临时文件(比如
params.tmp) - 用系统原子重命名命令替换目标文件(Unix-like用
mv params.tmp params.conf,Windows同磁盘下move命令也是原子操作) - 脚本每次循环开始时,读取
params.conf的完整内容
示例(Bash):
# 脚本循环部分 while true; do # 读取参数文件 source params.conf # 执行API请求 curl -X POST "https://api.example.com" -d "key=${API_KEY}&data=${REQUEST_DATA}" sleep 600 done # 修改参数时的操作(另一个终端) echo "API_KEY=new_key REQUEST_DATA=new_data" > params.tmp mv params.tmp params.conf
2. 信号触发参数重载
让脚本监听特定系统信号,收到信号时才重新加载参数,平时循环使用内存缓存值,既减少IO又避免读取风险:
- 脚本启动时加载初始参数到变量
- 注册信号处理函数(比如
SIGUSR1),函数内用原子文件方式读取新参数并更新变量 - 修改参数时,先写好完整的参数文件(原子替换方式),再给脚本进程发送信号
示例(Python):
import signal import time import subprocess # 初始化参数 api_key = "default_key" request_data = "default_data" def reload_params(signum, frame): global api_key, request_data # 读取原子替换后的参数文件 with open("params.conf", "r") as f: for line in f: key, val = line.strip().split("=", 1) if key == "API_KEY": api_key = val elif key == "REQUEST_DATA": request_data = val # 注册信号处理 signal.signal(signal.SIGUSR1, reload_params) # 循环请求API while True: # 执行请求 subprocess.run(["curl", "-X", "POST", "https://api.example.com", "-d", f"key={api_key}&data={request_data}"]) time.sleep(600)
修改参数后,给脚本进程发信号:kill -USR1 <脚本PID>
3. 命名管道(FIFO)传递参数
创建命名管道作为参数传递通道,利用管道的“消息完整性”特性,确保脚本要么读到完整新参数,要么没读到:
- 创建命名管道:
mkfifo param_pipe - 脚本每次循环前,尝试从管道读取参数(带短超时),读到完整内容就更新变量,没读到就用旧参数
- 修改参数时,将完整参数(比如JSON格式)写入管道
示例(Bash):
# 创建管道(仅需执行一次) mkfifo param_pipe # 脚本循环部分 api_key="default_key" request_data="default_data" while true; do # 尝试读取管道,超时0.1秒 if read -t 0.1 new_params < param_pipe; then # 解析JSON格式参数 api_key=$(echo "$new_params" | jq -r '.api_key') request_data=$(echo "$new_params" | jq -r '.request_data') fi # 执行请求 curl -X POST "https://api.example.com" -d "key=${api_key}&data=${REQUEST_DATA}" sleep 600 done # 修改参数时的操作(另一个终端) echo '{"api_key":"new_key", "request_data":"new_data"}' > param_pipe
4. 本地套接字通信
通过本地UDP/TCP套接字传递参数,确保参数以完整数据包形式发送,脚本收到后解析更新:
- 脚本启动本地UDP套接字,监听特定端口
- 每次循环前检查是否有新数据包,有则解析更新参数
- 修改参数时,通过本地套接字发送完整的参数JSON
示例(Python):
import socket import time import subprocess import json # 初始化参数 params = { "api_key": "default_key", "request_data": "default_data" } # 创建本地UDP套接字 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(("127.0.0.1", 9999)) # 设置非阻塞模式 sock.setblocking(False) while True: # 检查是否有新参数 try: data, addr = sock.recvfrom(1024) new_params = json.loads(data.decode()) params.update(new_params) except BlockingIOError: # 没有新数据,跳过 pass # 执行请求 subprocess.run([ "curl", "-X", "POST", "https://api.example.com", "-d", f"key={params['api_key']}&data={params['request_data']}" ]) time.sleep(600)
修改参数时,用脚本发送数据包:
import socket import json sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) new_params = {"api_key": "new_key", "request_data": "new_data"} sock.sendto(json.dumps(new_params).encode(), ("127.0.0.1", 9999)) sock.close()
内容的提问来源于stack exchange,提问作者JobWeek
相关产品推荐
相关产品推荐

