paramiko 执行多条语句时,get_pty=True参数的使用

本文介绍了解决SSH远程连接中多条命令无法全部执行的问题。通过调整Python代码中的参数配置,确保了诸如文件复制、路径切换及文件解压等操作能够顺利进行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ssh远程到其他机器上执行多条命令时,遇到有的命令不会执行成功,起初以为是远程过去执行命令的权限不够,不是以root用户的权限执行命令,所以在命令前加了sudo,发现依然不能全部执行成功,下面是最初执行的代码:

definstall_pkg(ip_list, copy_file_path, copy_to_path, cada_env_name):for pkg_ip in ip_list:
        print("pkg install on: ", pkg_ip)
        cmd = ""
        cmd += f"scp -r {copy_file_path} root@{pkg_ip}:{copy_to_path}; "
        print("cmd: ", cmd)
        os.system(cmd)
        print("Copy file complete!")
        time.sleep(2)
        ssh_remote = paramiko.SSHClient()
        ssh_remote.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_remote.connect(hostname=pkg_ip,
                           port=22,
                           username=username,
                           password=password)

        remote_cmd = ""
        remote_cmd += f"cp -r {copy_to_path}/{cada_env_name} /root/miniconda3/envs/; "
        remote_cmd += f"cd /root/miniconda3/envs/; "
        remote_cmd += f"tar -vxf {cada_env_name}; "
        print("install whl cmd is : ", remote_cmd)
        try:
            stdin, stdout, stderr = ssh_remote.exec_command(remote_cmd)
            print(stdout.readlines())
        except Exception as e:
            print("if exception is timeout, that's fine")
            print("exception is : ", e)
        finally:
            ssh_remote.close()
        print("install pkg on : ", pkg_ip)复制

上面这段代码执行的时候,不会执行最后一个解压命令:tar -vxf {cada_env_name};这个命令单执行的时候,文件解压会需要很长的时间。原因是由于如果直接写的话在每条命令后加分号执行时会报错,如果不加分号,分一条命令一条命令地执行,起不到作用,如切换路径等。经过百度,我在ssh的时候添加了look_for_keys=True和调用exec_command的时候加了get_pty=True就可以以成功执行所有命令了。下面是修改后的代码:

definstall_pkg(ip_list, copy_file_path, copy_to_path, cada_env_name):for pkg_ip in ip_list:
        print("pkg install on: ", pkg_ip)
        cmd = ""
        cmd += f"scp -r {copy_file_path} root@{pkg_ip}:{copy_to_path}; "
        print("cmd: ", cmd)
        os.system(cmd)
        print("Copy file complete!")
        time.sleep(2)
        ssh_remote = paramiko.SSHClient()
        ssh_remote.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_remote.connect(hostname=pkg_ip,
                           port=22,
                           username=username,
                           password=password,
                           look_for_keys=True)

        remote_cmd = ""
        remote_cmd += f"cp -r {copy_to_path}/{cada_env_name} /root/miniconda3/envs/; "
        remote_cmd += f"cd /root/miniconda3/envs/; "
        remote_cmd += f"tar -vxf {cada_env_name}; "
        print("install whl cmd is : ", remote_cmd)
        try:
            stdin, stdout, stderr = ssh_remote.exec_command(remote_cmd, get_pty=True)
            print(stdout.readlines())
        except Exception as e:
            print("if exception is timeout, that's fine")
            print("exception is : ", e)
        finally:
            ssh_remote.close()
        print("install pkg on : ", pkg_ip)复制

关于这个两个参数的使用,百度以下说明仅供参考:

look_for_keys(bool类型): 默认为True,就是会找你 .ssh 目录下有没有合适的密钥文件;

get_pty(bool类型):实际在远程执行sudo命令时,一般主机都会需要通过tty才能执行,通过把get_pty值设置为True,可以模拟tty;

<think>嗯,用户给了一个Python脚本,看起来是用Paramiko库实现将当前脚本传输到远程服务器并执行。现在用户希望我作为编程专家来回答这个问题,给出解决方案和相关解释,然后提出相关问题。首先,我需要仔细阅读用户提供的代码,理解其功能。代码里定义了一个transfer_and_run函数,接收主机名、用户名、密码和远程路径。函数内部读取当前脚本文件,使用Paramiko建立SSH连接,传输文件到远程服务器的指定路径,然后设置执行权限并运行脚本。最后在main部分调用这个函数,但示例中的参数需要替换成真实的凭证。 接下来,我需要检查这段代码是否有潜在的问题或可以优化的地方。例如,当前的脚本在传输自身到远程服务器后,会再次执行自己。但如果在远程执行没有条件判断,可能会导致无限循环,因为远程执行__name__还是'__main__',从而再次调用transfer_and_run,可能形成递归传输。所以需要确保在远程执行不会再次触发传输。另外,代码中的异常处理可能不够完善,比如没有捕获连接或文件传输中的异常,这可能导致程序崩溃而没有友好的错误提示。此外,密码明文传输存在安全隐患,建议使用密钥认证或者至少提示用户不要硬编码密码。 然后,我应该解释代码的工作原理,分步骤说明每个部分的功能,比如建立SSH连接、传输文件、执行命令等。同,指出潜在的问题,比如递归执行和安全问题,并提供改进建议,比如添加执行条件判断、异常处理和使用密钥认证。 最后,根据这个脚本涉及的知识点,提出相关问题,比如Paramiko的其他用法、避免递归执行的方法、替代的远程执行工具,以及安全建议等。</think>这是一个使用Paramiko库实现自传输执行Python脚本,以下是详细解释和改进建议: ```python import paramiko import os import sys def transfer_and_run(hostname, username, password, remote_path='/tmp'): # 获取当前脚本内容 with open(__file__, 'r') as f: script_content = f.read() # 创建SSH客户端 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: # 建立连接 ssh.connect(hostname, username=username, password=password) # 传输文件 sftp = ssh.open_sftp() remote_script_path = f"{remote_path}/{os.path.basename(__file__)}" with sftp.file(remote_script_path, 'w') as remote_file: remote_file.write(script_content) # 设置执行权限并运行(添加执行环境判断) command = f"chmod +x {remote_script_path} && python3 -c \"import os; os.system('python3 {remote_script_path}' if os.path.isfile('{remote_script_path}') else '')\"" stdin, stdout, stderr = ssh.exec_command(command) print(f"Output:\n{stdout.read().decode()}") print(f"Errors:\n{stderr.read().decode()}") except Exception as e: print(f"Error occurred: {str(e)}") finally: ssh.close() if __name__ == '__main__': # 添加本地执行判断防止递归 if not os.getenv('REMOTE_EXEC'): # 设置环境变量标记 os.environ['REMOTE_EXEC'] = '1' transfer_and_run( hostname='your_server_ip', username='your_username', password='your_password' ) else: print("This is remote execution") ``` 改进说明: 1. 添加了环境变量判断防止递归执行 2. 增加了异常处理捕获连接错误 3. 修改了远程执行命令,添加了文件存在性检查 4. 增加了安全退出机制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值