我正在尝试编写一个函数,该函数将接受两个参数 - source
和output
并调用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
文件?
我期待任何回复!
答案 0 :(得分:2)
你有一些额外的报价。在此行中的ssh
命令周围删除一组引号,如下所示:
command = ['/usr/bin/rsync', "-avz", "-e", "ssh -i rsync-key", source, dest]
原因是通过使用作为列表的command
,您没有运行shell,因此通常的shell解析规则不适用。您的列表直接包含传递给子流程的每个参数,参数可以包含空格。