【问题标题】:Using scp to transfer a single file into a remote folder that doesn't exist使用 scp 将单个文件传输到不存在的远程文件夹中
【发布时间】:2023-10-26 05:23:02
【问题描述】:

我正在编写一个 python 脚本,它监视一个目录并上传使用 scp 创建或修改的文件。没关系,除了我希望递归完成,如果用户在监视目录中创建目录,然后修改该新目录中的文件,我会遇到问题。

我可以很好地检测到目录创建和文件嵌套文件创建/修改。但是如果我尝试将该文件上传到远程服务器,它将无法正常工作,因为远程站点上的目录将不存在。有没有一种简单的方法可以在不递归复制创建的目录的情况下做到这一点?我想避免这种情况,因为如果远程文件夹存在,我不想删除它。

另外,请不要推荐rsync。它只能使用 ssh 和 scp。

【问题讨论】:

  • 你试过-r修饰符吗? (-r 表示“递归执行此复制”并根据需要构建文件夹)
  • 为什么不能使用rsync?只是你不喜欢吗?你有真正的理由不使用它吗?如果是这样,原因是什么?当您问“我如何做 A?请不要推荐工具 B”和“我如何做 A?”的通常回答时。是“使用工具 B”而你没有说为什么你不能使用工具 B,它往往会以错误的方式惹恼人们。另外,如果您告诉我们为什么不能使用它,这将有助于我们想出更好的答案。
  • 首先我不喜欢 rsync,但这不是我说我不想使用它的原因。我发现 rsync 非常慢,对于我正在执行的传输类型而言,它比 scp 慢得多。此外, rsync 甚至不能解决我的问题。我正在尝试手动执行此操作,因此我没有 rsync 差异计算的开销。我不希望它每次更新文件时都必须计算整个差异树。

标签: python scp


【解决方案1】:

虽然我认为您的特定应用程序会有自己的怪癖(就像我的一样),但这可能会让您走上正确的道路。下面是一个简短的 sn-p 脚本,我使用基于 paramiko 构建的 Fabric 将文件放到远程 EC2 实例上。还要注意我把 sudo 命令放在哪里,因为 Fabric 有自己的“sudo”类。这是我所指的那些怪癖之一。希望这对某人有所帮助。


from fabric.api import env, run, put, settings, cd
from fabric.contrib.files import exists

''' sudo apt-get install fabric Initially setup for interaction with an AWS EC2 instance At the terminal prompt run: fab ec2 makeRemoteDirectory changePermissions putScript '''

TARGETPATH = '/your/path/here'

def ec2(): env.hosts = ['your EC2 Instance or remote address'] env.user = 'user_name' env.key_filename = '/path/to/your/private_key.pem'

def makeRemoteDirectory(): if not exists('%s'%TARGETPATH): run('sudo mkdir %s'%TARGETPATH)

def changePermissions(): run('sudo chown -R %(user)s:%(user)s %(path)s'%{'user': env.user, 'path': TARGETPATH})

def putScript(): fileName = '/path/to/local/file' dirName = TARGETPATH put(fileName, dirName)

【讨论】:

    【解决方案2】:

    既然有ssh,就不能先创建目录吗?例如,给定一个具有绝对路径 /some/path/file.txt 的文件,在上传 file.txt 之前发出 mkdir -p /home/path

    更新:如果您希望减少事务的数量,更好的方法可能是在本地创建一个 tar 文件,传输该文件,然后解压缩它。

    【讨论】:

    • 这是我能想到的唯一解决方案。我只是希望有一种方法可以通过 scp 在 1 个事务中执行此操作,而无需依赖 mkdir 失败
    • @Falmarri,查看我的更新。不知道除此之外还有什么更好的方法。
    • 是的,我可能会通过 ssh 创建目录
    【解决方案3】:

    它不完全是 scp,但 sftp 可以将 -b 参数与批处理文件一起使用。你可以发送一个 mkdir 和一个 put。

    【讨论】: