python远程执行Linux命令(本地和远程)————附带详细代码

1 本地执行Linux指令

import subprocess
def localSsh(command):
    print(f"开始在本地服务器上执行指令:{command}")
    p = subprocess.Popen([command],
                         stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE, shell=True)
    out = p.stdout.read().decode('utf-8')
    # regex = r'time=(.+?)ms'
    print(out)

2 远程执行Linux指令

import paramiko
# 远程登陆操作系统
def remoteSsh(sys_ip, username, command, password=''):
    try:
        # 创建ssh客户端
        client = paramiko.SSHClient()
        # 第一次ssh远程时会提示输入yes或者no
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        if len(password) == 0:
            print('互信方式远程连接')
            key_file = paramiko.RSAKey.from_private_key_file("/root/.ssh/id_rsa")
            client.connect(sys_ip, 22, username=username, pkey=key_file, timeout=20)
        else:
            print('密码方式远程连接') # base64.b64decode(password).decode()
            client.connect(sys_ip, 22, username=username, password=password, timeout=20)
        print(f"开始在远程服务器上执行指令:{command}")
        # 执行查询命令
        stdin, stdout, stderr = client.exec_command(f"""{command}""", get_pty=True)
        # 获取查询命令执c行结果,返回的数据是一个list
        result = stdout.read().decode('utf-8')
        print(f"{sys_ip}执行结果:", result)

        error = stderr.read().decode('utf-8')
        if error != "":
            print(f"{sys_ip}错误信息:", error)
        else:
            pass
    except Exception as e:
        print(e)
    finally:
        client.close()

# 批量执行同一命令
def batchExecuteRemoteCommand(host_list, command):
    import threading
    thread_list = []
    for ip, username, password in host_list:
        thread = threading.Thread(target = remoteSsh, args = (ip,username,password,command))
        thread_list.append(thread)#将生成的线程添加到列表里
    for t in thread_list:
        t.start() #开始执行线程
    for t in thread_list:
        t.join() #挂起线程,到所有线程结束

3 本地执行scp命令(不需要输入密码)

def scpFileToRemoteNode(username, aim_ip, password, source_file_path, aim_file_path, port=22):
    '''
    拷贝软件包到远程节点,默认使用root用户22号端口传输
    :return: 0 表示执行成功
    '''
    import pexpect
    password_key = '.*assword.*'
    command = f'scp {source_file_path}  {username}@{aim_ip}:{aim_file_path}'
    print("开始在本地服务器上执行指令: ", command)
    try:
        execute = pexpect.spawn(command)
        execute.expect(password_key)
        execute.sendline(password)
        execute.expect(pexpect.EOF)
        print("拷贝文件到远程服务成功")
    except:
        print("拷贝文件到远程服务器失败")

4 测试代码

下面以一个远程允许Airflow的代码为例:

if __name__ == '__main__':
    airflow_server_ip = "10.20.6.66"
    airflow_server_username = "root"
    airflow_server_password = "123456"
    import sys
    import os
    if len(sys.argv) > 1:
        airflow_yml_path = sys.argv[1]
        with open(airflow_yml_path) as f:
            airflow_dag_yml_first_line = f.readlines()[0].rstrip()
        airflow_dag_id = airflow_dag_yml_first_line[0:len(airflow_dag_yml_first_line) - 1]
        airflow_py_base_path = os.getcwd() + "/"
        airflow_py_path = airflow_py_base_path + "template_" + airflow_dag_id + ".py"
        aim_airflow_dag_yml_path = f"/root/airflow/dags/template_{airflow_dag_id}.yml"
        aim_airflow_py_path = f"/root/airflow/dags/template_{airflow_dag_id}.py"
        print("产生Airflow运行文件")
        airflow_run_code = airflow_run_code.replace("sys.argv[1]", aim_airflow_dag_yml_path)
        with open (airflow_py_path, 'w') as file_object:
            file_object.write(airflow_run_code)

        print('清除远程服务器原始配置文件')
        server_command = f"rm -rf {aim_airflow_dag_yml_path}; rm -rf {aim_airflow_py_path}"
        remoteSsh(sys_ip=airflow_server_ip, username=airflow_server_username, command=server_command,  password=airflow_server_password)

        print('开始复制Airflow配置文件到远程服务器')
        # 使用账号密码远程scp
        if len(airflow_server_password) == 0:
            scp_command = f"scp {airflow_yml_path} root@{airflow_server_ip}:{aim_airflow_dag_yml_path}; scp {airflow_py_path} root@{airflow_server_ip}:{aim_airflow_py_path}"
            localSsh(scp_command)
        else:
            scpFileToRemoteNode(username=airflow_server_username, aim_ip=airflow_server_ip, password=airflow_server_password, source_file_path=airflow_yml_path, aim_file_path=aim_airflow_dag_yml_path)
            scpFileToRemoteNode(username=airflow_server_username, aim_ip=airflow_server_ip, password=airflow_server_password, source_file_path=airflow_py_path, aim_file_path=aim_airflow_py_path)

        print('开始连接远程服务器并执行Airflow任务')
        server_command = f"python3 {aim_airflow_py_path}  &&  sleep 300s && airflow dags unpause {airflow_dag_id}"
        remoteSsh(sys_ip=airflow_server_ip, username=airflow_server_username, command=server_command, password=airflow_server_password)
    else:
        print('参数不匹配')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星蓝雨

如果觉得文章不错,可以请喝咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值