You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过Python脚本输入HPC集群密码实现scp文件传输

如何在Python脚本中自动输入SCP的HPC集群密码

嗨,我来帮你搞定这个自动输入密码的问题~你之前用os.system()执行scp命令时没法自动传密码,是因为os.system()没办法和子进程的输入流交互,直接输出密码根本传不到scp的输入里。下面给你几个可行的解决方案,从实用到安全排序:

方法1:用pexpect处理交互式命令

pexpect是专门用来处理需要交互式输入的命令行工具,正好适配这个场景。

步骤:

  1. 先安装pexpect:
pip install pexpect
  1. 改写你的脚本:
import pexpect

password = 'password'
clusterpath = 'myname@cluster.hpc1.cs.univ.edu:/Projects/re*'
localpath = 'Projects/.'

# 启动scp命令,等待密码提示
child = pexpect.spawn(f'scp {clusterpath} {localpath}')
# 匹配密码输入提示(不同集群的提示可能是"Password:"或者"password:",注意大小写)
child.expect('Password:')
# 发送密码,记得加换行符模拟回车
child.sendline(password)
# 等待命令执行完成
child.expect(pexpect.EOF)
# 可以打印输出看看执行结果
print(child.before.decode())

注意哦:不同HPC集群的密码提示文本可能不一样,如果匹配不到,你可以先手动执行scp命令,看看实际的提示是什么,再修改child.expect()里的内容。

方法2:用paramiko直接实现SCP(更Pythonic)

paramiko是Python的SSH/SCP实现库,不需要调用系统的scp命令,直接在代码里完成文件传输,灵活度更高。

步骤:

  1. 安装paramiko和scp依赖:
pip install paramiko scp
  1. 示例代码(支持批量传输通配符匹配的文件):
import paramiko
from scp import SCPClient

# 建立SSH连接
ssh = paramiko.SSHClient()
# 自动添加未知的主机密钥(生产环境建议手动配置,更安全)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

password = 'password'
hostname = 'cluster.hpc1.cs.univ.edu'
username = 'myname'

try:
    ssh.connect(hostname, username=username, password=password)
    # 创建SCP客户端
    with SCPClient(ssh.get_transport()) as scp:
        # 先通过SSH命令获取通配符匹配的文件列表
        stdin, stdout, stderr = ssh.exec_command('ls /Projects/re*')
        files = stdout.read().decode().strip().split('\n')
        # 逐个下载文件到本地
        for file in files:
            if file:  # 跳过空行
                scp.get(file, localpath='Projects/.')
    print("文件传输完成!")
finally:
    ssh.close()

方法3:设置SSH密钥登录(最安全,强烈推荐)

上面两种方法都需要在代码里写明文密码,风险很高。最安全的方式是设置SSH密钥对,以后不管是手动scp还是脚本执行,都不需要输密码。

步骤:

  1. 在本地生成SSH密钥对(一路回车用默认配置即可):
ssh-keygen -t rsa
  1. 将公钥上传到HPC集群(执行时需要输一次密码,之后就永久生效):
ssh-copy-id myname@cluster.hpc1.cs.univ.edu
  1. 之后你的原脚本直接就能用,完全不用处理密码:
import subprocess

clusterpath = 'myname@cluster.hpc1.cs.univ.edu:/Projects/re*'
localpath = 'Projects/.'
# 用subprocess比os.system更推荐,能捕获执行状态和输出
subprocess.run(['scp', clusterpath, localpath], check=True)

内容的提问来源于stack exchange,提问作者Commoner

火山引擎 最新活动