在python

时间:2017-07-12 21:35:08

标签: python ssh rsync

我正在尝试编写一个函数,该函数将接受两个参数 - sourceoutput并调用rsync以将源文件复制到输出文件夹。以下是该功能的内容:

# Run rsync
try:
    command = ['/usr/bin/rsync', "-avz", "-e", '"ssh -i rsync-key"', source, dest]
    p = Popen(command, stdout=PIPE, stderr=PIPE)
    stdo, stde = p.communicate()
    if p.returncode != 0:
        raise Exception("Failed to run rsync command {} with return code of {}. {}".format(' '.join(command), p.returncode, stde))
    else:
        logging.info("Done running rsync command {} with return code of {}. {}".format(' '.join(command), p.returncode, stdo))
except Exception as ex:
    raise Exception("Failed to run rsync command {}. {}".format(' '.join(command), ex))

rsync-key是与python脚本位于同一目录中的私有ssh密钥(具有权限700),我在我的服务器上的authorized_keys文件中有公钥(为了测试我的脚本,我是尝试从同一服务器复制文件。)

我正在使用源文件USERNAME@localhost:/home/USERNAME/.vimrc和输出文件夹tmp/测试脚本。这两个地方都存在。

如果我使用本地路径(而不是USERNAME@localhost:...)运行它,它也运行得很好。

当我运行这个python程序时,我得到以下输出

CRITICAL $(asctime)-15s Error with rsync: Failed to run rsync command /usr/bin/rsync -avz -e "ssh -i rsync-key" USERNAME@localhost:/home/USERNAME/.vimrc tmp/. 
Failed to run rsync command /usr/bin/rsync -avz -e "ssh -i rsync-key" USERNAME@localhost:/home/USERNAME/.vimrc tmp/ with return code of 14. rsync: 
Failed to exec ssh -i rsync-key: No such file or directory (2)
rsync error: error in IPC code (code 14) at pipe.c(84) [receiver=3.0.4]
rsync: connection unexpectedly closed (0 bytes received so far) [receiver]
rsync error: error in IPC code (code 14) at io.c(641) [receiver=3.0.4]
Traceback (most recent call last):
  File "fetch.py", line 95, in main
    rsync(args.source_file, args.output_dir)
  File "fetch.py", line 57, in rsync
    raise Exception("Failed to run rsync command {}. {}".format(' '.join(command), ex))

但是,如果我在普通shell中运行相同的命令/usr/bin/rsync -avz -e "ssh -i rsync-key" USERNAME@localhost:/home/USERNAME/.vimrc tmp/,它会毫无障碍地运行。知道为什么python似乎无法找到我的rsync-key文件?

我期待任何回复!

1 个答案:

答案 0 :(得分:2)

你有一些额外的报价。在此行中的ssh命令周围删除一组引号,如下所示:

command = ['/usr/bin/rsync', "-avz", "-e", "ssh -i rsync-key", source, dest]

原因是通过使用作为列表的command,您没有运行shell,因此通常的shell解析规则不适用。您的列表直接包含传递给子流程的每个参数,参数可以包含空格。