在 python 中从 Popen 中执行时 rsync 找不到文件
rsync cannot find file when executed from within Popen in python
我正在尝试编写一个函数,它将接受两个参数 - 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
文件中有 public 密钥在我的服务器上(为了测试我的脚本,我试图从同一台服务器复制文件)。
我正在使用源文件 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
文件吗?
我期待任何回复!
你那里有一些额外的引号。删除此行中 ssh
命令周围的一组引号,如下所示:
command = ['/usr/bin/rsync', "-avz", "-e", "ssh -i rsync-key", source, dest]
原因是,通过使用作为列表的 command
,您不会 运行 通过 shell,因此通常的 shell 解析规则不会申请。您的列表直接包含传递给子进程的每个参数,参数可以包含空格。
我正在尝试编写一个函数,它将接受两个参数 - 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
文件中有 public 密钥在我的服务器上(为了测试我的脚本,我试图从同一台服务器复制文件)。
我正在使用源文件 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
文件吗?
我期待任何回复!
你那里有一些额外的引号。删除此行中 ssh
命令周围的一组引号,如下所示:
command = ['/usr/bin/rsync', "-avz", "-e", "ssh -i rsync-key", source, dest]
原因是,通过使用作为列表的 command
,您不会 运行 通过 shell,因此通常的 shell 解析规则不会申请。您的列表直接包含传递给子进程的每个参数,参数可以包含空格。