Python 脚本如何通过 SSH 设置 Linux 环境变量?

自己最近使用 Python 写 Oracle,WebLogic 等自动化安装脚本。

自己还不会 Shell 编程,所以使用了 Python, 以后学了 Shell 编程,再使用 Shell 重写。

有一个问题是使用 subprocess.call(['source /etc/profile'], shell=True)

类似这样的命令可以被执行,但不会生效,$PATH 并不改变。

上网查了几篇文章,说 SSH 连接的终端并不是实际意义上的 bash

目前可以使用某个命令的绝对地址,但这样有点麻烦,有些地址很长,强迫症都犯了。

有没有人做过类似的东西,有没有更好的方法,请大佬指教一二。


Python 脚本如何通过 SSH 设置 Linux 环境变量?

12 回复

每次 subprocess.call 都是单独的环境吧,你把所有命令拼成一行。只调用一次 subprocess.call


import paramiko
import os

def set_env_via_ssh(hostname, username, password, env_dict):
    """
    通过SSH设置Linux环境变量
    
    参数:
        hostname: 远程主机地址
        username: SSH用户名
        password: SSH密码
        env_dict: 要设置的环境变量字典 {变量名: 值}
    """
    # 创建SSH客户端
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    try:
        # 连接远程主机
        client.connect(hostname, username=username, password=password)
        
        # 对于每个环境变量,写入到~/.bashrc
        for key, value in env_dict.items():
            # 构建设置环境变量的命令
            env_line = f'export {key}="{value}"\n'
            
            # 检查是否已存在该变量设置
            check_cmd = f'grep -n "export {key}=" ~/.bashrc || echo "not found"'
            stdin, stdout, stderr = client.exec_command(check_cmd)
            result = stdout.read().decode().strip()
            
            if result != "not found":
                # 如果已存在,先删除原有行
                line_num = result.split(':')[0]
                delete_cmd = f'sed -i "{line_num}d" ~/.bashrc'
                client.exec_command(delete_cmd)
            
            # 追加新的环境变量设置
            append_cmd = f'echo \'{env_line}\' >> ~/.bashrc'
            client.exec_command(append_cmd)
            
            # 立即生效(当前会话)
            immediate_cmd = f'export {key}="{value}"'
            client.exec_command(immediate_cmd)
            
            print(f"已设置环境变量: {key}={value}")
        
        # 也可以选择写入到/etc/environment(需要sudo权限)
        # 或者写入到~/.profile、~/.bash_profile等
        
    except paramiko.AuthenticationException:
        print("SSH认证失败,请检查用户名和密码")
    except paramiko.SSHException as e:
        print(f"SSH连接错误: {e}")
    except Exception as e:
        print(f"发生错误: {e}")
    finally:
        client.close()

# 使用示例
if __name__ == "__main__":
    # 配置SSH连接信息
    HOST = "192.168.1.100"  # 远程主机IP
    USER = "your_username"  # SSH用户名
    PASS = "your_password"  # SSH密码
    
    # 要设置的环境变量
    environment_vars = {
        "JAVA_HOME": "/usr/lib/jvm/java-11-openjdk",
        "APP_HOME": "/opt/myapp",
        "DATABASE_URL": "postgresql://user:pass@localhost/db"
    }
    
    # 执行设置
    set_env_via_ssh(HOST, USER, PASS, environment_vars)

这个脚本用了paramiko库来SSH连接Linux服务器,主要做了几件事:

  1. 先检查~/.bashrc里有没有已经存在的环境变量设置,有的话就删掉原来的
  2. 把新的环境变量追加到~/.bashrc文件末尾
  3. 同时用export命令让当前会话立即生效

用的时候记得先装paramiko:pip install paramiko,然后把HOST、USER、PASS换成你自己的服务器信息,environment_vars字典里放你要设的变量。

注意这方法修改的是用户级别的环境变量(~/.bashrc),如果要在系统级别设置(/etc/environment)或者给所有用户生效,需要sudo权限,而且得用不同的文件。

总结:用paramiko SSH连接后修改bashrc文件来设置环境变量。

二楼正解

subprocess.call 会生成一个子 shell 来执行,直接完成后就退出了,你环境变量设置到子 shell 的环境变量里面去了

subproces 的 env 设 PATH

ssh 连接的时候是可以选择传递制定的环境变量的,不过不知道 python 的封装有没有暴露相应的配置项。
另外环境变量是在父子进程之间传递的,你一个 subprocess 执行完就退出自然啥都不剩。
并且 source 是 shell 内置命令,必须在 shell 中执行。

如果想要用你的方式实现的话,需要这么干

bash -c ‘source xxx; ls’

env = 'xxxxx’
subprocess.Popen(RUN_COMMAND, env = env, shell=True)

wweirAnsenxiaketleido 原来是这样,我马上去试试,多谢多谢。/手动感谢

好的,非常感谢

楼主为什么不用 ansible 试试

某司小小实习生,负责人是让我用 Python 来写。/手动无奈

回到顶部