影刀RPA 环境变量管理:读取与设置

作者:林焱

什么情况用

在这里插入图片描述

你的影刀流程需要根据不同的电脑自动适配路径——在开发机上用D:/data,在生产机上用E:/data?你想让敏感信息(密码、密钥)不硬编码在流程中,而是通过环境变量传入?你需要调用其他程序,但它的路径在不同电脑上不一样?

环境变量管理是让流程跨环境运行的基础。通过读取系统环境变量,流程可以自动适配不同电脑的配置,不需要每次换电脑都改代码。

本文讲清楚:怎么读取和设置环境变量、在影刀RPA中怎么用、怎么用环境变量管理敏感信息。


在这里插入图片描述

怎么做

一、读取环境变量

import os

# ===== 基本读取 =====
# 方式1:os.environ(字典方式)
db_host = os.environ.get("DB_HOST", "localhost")  # 不存在返回默认值
python_path = os.environ.get("PYTHONPATH", "")     # 不存在返回空字符串

# 方式2:os.getenv()(更简洁)
db_host = os.getenv("DB_HOST", "localhost")
api_key = os.getenv("API_KEY", "")

# 方式3:直接索引(不存在会报KeyError)
try:
    db_host = os.environ["DB_HOST"]
except KeyError:
    db_host = "localhost"

# ===== 读取常用系统环境变量 =====
# 系统相关

[video(video-7LmDT5KF-1784577931506)(type-csdn)(url-https://live.csdn.net/v/embed/525010)(image-https://v-blog.csdnimg.cn/asset/f4faa587144cb7070f19e8b36813806b/cover/Cover0.jpg)(title-店群矩阵自动化突破运营极限!)]

computer_name = os.environ.get("COMPUTERNAME", "")        # 电脑名
username = os.environ.get("USERNAME", "")                 # 用户名
user_profile = os.environ.get("USERPROFILE", "")          # 用户目录
temp_dir = os.environ.get("TEMP", "")                     # 临时目录
app_data = os.environ.get("APPDATA", "")                  # AppData目录
program_files = os.environ.get("PROGRAMFILES", "")        # Program Files目录

# 路径相关
path = os.environ.get("PATH", "")                         # 系统PATH
home = os.environ.get("HOMEPATH", "")                     # Home路径
windir = os.environ.get("WINDIR", "")                     # Windows目录

print(f"电脑名: {computer_name}")
print(f"用户名: {username}")
print(f"临时目录: {temp_dir}")
print(f"用户目录: {user_profile}")

二、设置环境变量

在这里插入图片描述

import os

# ===== 在Python进程中设置(仅当前进程有效) =====
os.environ["RPA_CONFIG_PATH"] = "D:/config"
os.environ["RPA_ENV"] = "production"
os.environ["RPA_DEBUG"] = "true"

# 设置后可以在当前进程的任何地方读取
print(os.getenv("RPA_CONFIG_PATH"))  # D:/config

# ===== 注意:Python中设置的环境变量只在当前进程有效 =====
# 不会影响系统环境变量
# 子进程会继承当前进程的环境变量
# 进程结束后环境变量消失

# ===== 启动子进程时传递环境变量 =====
import subprocess

# 子进程会继承父进程的环境变量
result = subprocess.run(
    ["python", "script.py"],
    env=os.environ  # 传递当前环境变量(默认行为)
)

# 自定义子进程的环境变量
custom_env = os.environ.copy()
custom_env["CUSTOM_VAR"] = "custom_value"
result = subprocess.run(
    ["python", "script.py"],
    env=custom_env
)

三、永久设置系统环境变量

import subprocess
import ctypes
import os

def set_system_env_variable(name, value, scope="user"):
    """
    永久设置系统环境变量
    scope: "user"=用户级, "system"=系统级(需要管理员权限)
    """
    if scope == "user":
        # 用户级环境变量(不需要管理员权限)
        # 通过注册表设置
        import winreg
        key = winreg.OpenKey(
            winreg.HKEY_CURRENT_USER,
            "Environment",
            0,
            winreg.KEY_SET_VALUE
        )
        winreg.SetValueEx(key, name, 0, winreg.REG_EXPAND_SZ, value)
        winreg.CloseKey(key)
    elif scope == "system":
        # 系统级环境变量(需要管理员权限)
        import winreg
        key = winreg.OpenKey(
            winreg.HKEY_LOCAL_MACHINE,
            r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment",
            0,
            winreg.KEY_SET_VALUE
        )
        winreg.SetValueEx(key, name, 0, winreg.REG_EXPAND_SZ, value)
        winreg.CloseKey(key)
    
    # 通知系统环境变量已更改(让其他程序能感知到)
    # 发送WM_SETTINGCHANGE消息
    HWND_BROADCAST = 0xFFFF
    WM_SETTINGCHANGE = 0x001A
    res = ctypes.c_long()
    ctypes.windll.user32.SendMessageTimeoutW(
        HWND_BROADCAST,
        WM_SETTINGCHANGE,
        0,
        "Environment",
        0x0002,  # SMTO_ABORTIFHUNG
        5000,
        ctypes.byref(res)
    )
    
    print(f"已设置环境变量 {name}={value}{scope}级)")


# 使用
set_system_env_variable("RPA_DATA_DIR", "D:/rpa_data", scope="user")

四、环境变量管理敏感信息

在这里插入图片描述

import os

class EnvConfig:
    """基于环境变量的配置管理"""
    
    # 配置项定义:key → (环境变量名, 默认值, 转换函数)
    CONFIG_ITEMS = {
        "db_host":      ("DB_HOST", "localhost", str),
        "db_port":      ("DB_PORT", "3306", int),
        "db_name":      ("DB_NAME", "rpa_db", str),
        "db_user":      ("DB_USER", "root", str),
        "db_password":  ("DB_PASSWORD", "", str),  # 敏感信息
        "api_key":      ("API_KEY", "", str),       # 敏感信息
        "api_secret":   ("API_SECRET", "", str),    # 敏感信息
        "max_pages":    ("MAX_PAGES", "10", int),
        "timeout":      ("TIMEOUT", "30", int),
        "retry_count":  ("RETRY_COUNT", "3", int),
        "debug":        ("DEBUG", "false", lambda x: x.lower() == "true"),
        "output_dir":   ("OUTPUT_DIR", "D:/output", str),
    }
    
    @classmethod
    def get(cls, key):
        """获取配置值"""
        if key not in cls.CONFIG_ITEMS:
            raise KeyError(f"未知配置项: {key}")
        
        env_name, default, converter = cls.CONFIG_ITEMS[key]
        raw_value = os.environ.get(env_name, str(default))
        
        try:
            return converter(raw_value)
        except (ValueError, TypeError):
            return converter(default)
    
    @classmethod
    def get_all(cls):
        """获取所有配置"""
        return {key: cls.get(key) for key in cls.CONFIG_ITEMS}
    
    @classmethod
    def validate(cls):
        """验证必填配置"""
        missing = []
        for key, (env_name, default, _) in cls.CONFIG_ITEMS.items():
            if default == "" and not os.environ.get(env_name):
                missing.append(env_name)
        
        if missing:
            print("以下环境变量未设置:")
            for name in missing:
                print(f"  - {name}")
            return False
        return True


# 使用
config = EnvConfig

# 读取配置
db_host = config.get("db_host")
db_port = config.get("db_port")
db_password = config.get("db_password")
max_pages = config.get("max_pages")
debug = config.get("debug")

# 验证必填项
if config.validate():
    print("配置验证通过")
else:
    print("配置不完整,请设置环境变量")

五、自动适配不同电脑

import os
import socket

class PathManager:
    """自动适配不同电脑的路径管理"""
    
    def __init__(self):
        self.computer_name = os.environ.get("COMPUTERNAME", socket.gethostname())
        self.username = os.environ.get("USERNAME", "")
        
        # 根据电脑名设置不同的路径配置
        self.COMPUTER_CONFIGS = {
            "DESKTOP-DEV": {
                "data_dir": "D:/data",
                "output_dir": "D:/output",
                "log_dir": "D:/logs",
                "temp_dir": "D:/temp",
            },
            "SERVER-PROD": {
                "data_dir": "E:/rpa/data",
                "output_dir": "E:/rpa/output",
                "log_dir": "E:/rpa/logs",
                "temp_dir": "C:/temp",
            },
        }
        
        # 默认配置
        self.default_config = {
            "data_dir": os.path.join(os.environ.get("USERPROFILE", ""), "data"),
            "output_dir": os.path.join(os.environ.get("USERPROFILE", ""), "output"),
            "log_dir": os.path.join(os.environ.get("USERPROFILE", ""), "logs"),
            "temp_dir": os.environ.get("TEMP", "C:/temp"),
        }
    
    def get_path(self, key):
        """获取路径"""
        # 优先级:环境变量 > 电脑特定配置 > 默认配置
        env_key = f"RPA_{key.upper()}"
        
        # 1. 环境变量
        env_value = os.environ.get(env_key)
        if env_value:
            return env_value
        
        # 2. 电脑特定配置
        if self.computer_name in self.COMPUTER_CONFIGS:
            if key in self.COMPUTER_CONFIGS[self.computer_name]:
                return self.COMPUTER_CONFIGS[self.computer_name][key]
        
        # 3. 默认配置
        return self.default_config.get(key, "")
    
    def ensure_dirs(self):
        """确保所有目录存在"""
        for key in ["data_dir", "output_dir", "log_dir", "temp_dir"]:
            path = self.get_path(key)
            if path:
                os.makedirs(path, exist_ok=True)
                print(f"目录就绪: {key} = {path}")


# 使用
pm = PathManager()
pm.ensure_dirs()

data_dir = pm.get_path("data_dir")
output_dir = pm.get_path("output_dir")
print(f"数据目录: {data_dir}")
print(f"输出目录: {output_dir}")

六、在影刀RPA中使用环境变量

在这里插入图片描述

影刀流程中,可以用以下方式使用环境变量:

1. 在【执行Python代码】中用os.environ读取
2. 在影刀的表达式中用 %RPA_DATA_DIR% 引用(如果影刀支持)
3. 在影刀的变量管理中创建"环境变量"类型的变量
4. 通过配置文件间接使用
# 在影刀Python代码块中的实际使用

# 1. 读取配置路径
config_path = os.environ.get("RPA_CONFIG_PATH", "config.json")

# 2. 读取数据库密码(不硬编码在流程中)
db_password = os.environ.get("RPA_DB_PASSWORD", "")
if not db_password:
    print("警告:未设置RPA_DB_PASSWORD环境变量")

# 3. 根据环境变量决定运行模式
debug_mode = os.environ.get("RPA_DEBUG", "false").lower() == "true"
if debug_mode:
    print("=== 调试模式 ===")

# 4. 写入影刀变量供后续指令使用
yd_var["data_dir"] = os.environ.get("RPA_DATA_DIR", "D:/data")
yd_var["output_dir"] = os.environ.get("RPA_OUTPUT_DIR", "D:/output")
yd_var["debug_mode"] = debug_mode

有什么坑

在这里插入图片描述

坑1:Python设置的环境变量不会永久生效

现象:用os.environ["VAR"] = "value"设置了环境变量,但在CMD或影刀的其他流程中读不到。

原因os.environ设置的环境变量只在当前Python进程及其子进程中有效。进程结束后就消失了。不会写入系统环境变量。

解决:如果需要永久设置,用注册表方式(见上文set_system_env_variable函数)。如果只是在当前流程中使用,os.environ就够了。

在这里插入图片描述

坑2:环境变量名大小写问题

现象:在Windows上os.environ["PATH"]os.environ["path"]都能读到,但在Linux上只有大写PATH才行。

原因:Windows环境变量不区分大小写,Linux/Mac区分大小写。

temu店群自动化报活动案例


在这里插入图片描述

解决:环境变量名统一用大写。使用os.environ.get("VAR_NAME")时,Windows上大小写都行,但为了跨平台兼容,统一用大写。

坑3:PATH环境变量修改后不立即生效

现象:在Python中修改了PATH环境变量,但subprocess.run(["program"])还是找不到程序。

原因:修改os.environ["PATH"]后,Python进程的PATH确实变了,但有些程序的查找依赖系统级PATH缓存。

解决:修改PATH后,用完整路径调用程序,或者在子进程中显式设置env参数。修改PATH后可能需要新建子进程才能生效。

在这里插入图片描述

坑4:环境变量中包含特殊字符

现象:环境变量值中包含%$;等特殊字符,读取时被解析或截断。

原因:Windows环境变量中%VAR%会被展开,分号;是PATH的分隔符。

解决:如果值中需要包含特殊字符,用注册表设置时用REG_EXPAND_SZ类型避免展开。读取后做适当处理。路径中避免使用特殊字符。
在这里插入图片描述

坑5:影刀流程运行时环境变量和手动运行不一致

现象:在CMD中设置了环境变量,但影刀流程运行时读不到。

原因:影刀可能是作为Windows服务运行的,服务运行的环境变量和用户登录后的环境变量可能不同。

解决:通过系统环境变量(注册表方式)设置,确保所有进程都能读到。或者在影刀流程启动时,先运行一个初始化脚本设置需要的环境变量。检查影刀是以服务方式运行还是以用户方式运行,对应的环境变量来源不同。

更多推荐