rsync+;python子进程中的ssh在目录名中获取空格错误

rsync+;python子进程中的ssh在目录名中获取空格错误,python,ssh,rsync,quoting,Python,Ssh,Rsync,Quoting,当我运行Python应用程序(在本地同步远程目录)时,如果包含我的应用程序的目录的名称中有一个或多个空格,我会遇到问题。 目录名出现在ssh选项中,如“-o UserKnownHostsFile=”和“-i”。 我尝试在生成命令字符串的函数中使用双引号路径,但什么都没有。我还尝试这样替换空格:path.replace(“,\\”),但它不起作用。 请注意,我的代码使用不带空格的dirnames。 ssh返回的错误是“行尾的垃圾”(代码12) 生成的命令行似乎正常 rsync -rztv --de

当我运行Python应用程序(在本地同步远程目录)时,如果包含我的应用程序的目录的名称中有一个或多个空格,我会遇到问题。 目录名出现在ssh选项中,如“
-o UserKnownHostsFile=
”和“
-i
”。 我尝试在生成命令字符串的函数中使用双引号路径,但什么都没有。我还尝试这样替换空格:
path.replace(“,\\”)
,但它不起作用。 请注意,我的代码使用不带空格的dirnames。 ssh返回的错误是“行尾的垃圾”(代码12) 生成的命令行似乎正常

rsync -rztv --delete --stats --progress --timeout=900 --size-only --dry-run \
    -e 'ssh -o BatchMode=yes \
    -o UserKnownHostsFile="/cygdrive/C/Users/my.user/my\ app/.ssh/known_hosts" \
    -i "/cygdrive/C/Users/my.user/my\ app/.ssh/id_rsa"'
    user@host:/home/user/folder/ "/cygdrive/C/Users/my.user/my\ app/folder/"

我做错了什么?谢谢大家!

从sub命令返回的数据包含空格作为分隔符。尝试更新内部字段分隔符(IFS)列表,如下所示:

# store a copy of the current IFS
SAVEIFS=$IFS;
# set IFS to be newline-only
IFS=$(echo -en "\n\b");

# execute your command(s)
rsync -rztv --delete --stats --progress --timeout=900 --size-only --dry-run -e 'ssh -o BatchMode=yes -o UserKnownHostsFile="/cygdrive/C/Users/my.user/my\ app/.ssh/known_hosts" -i "/cygdrive/C/Users/my.user/my\ app/.ssh/id_rsa"' user@host:/home/user/folder/ "/cygdrive/C/Users/my.user/my\ app/folder/"

# put the original IFS back
IFS=$SAVEIFS;

我没有使用您的命令进行测试,尽管它在我过去尝试过的所有情况下都有效。

要避免转义问题,请使用原始字符串

raw_string = r'''rsync -rztv --delete --stats --progress --timeout=900 --size-only --dry-run -e 'ssh -o BatchMode=yes -o UserKnownHostsFile="/cygdrive/C/Users/my.user/my app/.ssh/known_hosts" -i "/cygdrive/C/Users/my.user/my app/.ssh/id_rsa"' user@host:/home/user/folder/ "/cygdrive/C/Users/my.user/my app/folder/"'''

sp = subprocess.Popen(raw_string, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = sp.communicate()[0]

您是否尝试过将命令构建为参数列表?我刚刚遇到了一个类似的问题,即为ssh连接传递密钥文件:

command = [
  "rsync",
  "-rztv",
  "--delete",
  "--stats",
  "--progress",
  "--timeout=900",
  "--size-only",
  "--dry-run",
  "-e",
  "ssh -o BatchMode=yes -o UserKnownHostsFile='/cygdrive/C/Users/my.user/my\ app/.ssh/known_hosts' -i '/cygdrive/C/Users/my.user/my\ app/.ssh/id_rsa'",
  "user@host:/home/user/folder/",
  "/cygdrive/C/Users/my.user/my\ app/folder/"
]

sp = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = sp.communicate()[0]

抱歉,我使用Python(确切地说,我调用了子流程中的命令),我在您的原始字符串中插入了我的vars,如下所示:r''-e'ssh-o BatchMode=yes-o UserKnownHostsFile=“'''+basePath+self.''+basePath+self.'-I'''+basePath+self.\uu certPathName+''''''self.''srcUser+'@'+self.''srcHost+'':''srcPath+'''''''''''''''''+basePath+dstPath+''''''''''但我总是获得“命令行0:行尾垃圾”。你为什么要这样做。。?您正在破坏使用原始字符串工具的目的-它会自动转义您输入的所有内容。请尝试两种方法,原始字符串=r''/usr/bin/rsync-e/usr/bin/ssh-o BatchMode=yes-o UserKnownHostsFile=“%s/%s”-i”%s/%s”%s@%s:%s”%s/%s'%(basePath,self.\u knownHostsPathName,basePath,self.\u certPathName,self.\u srcUser,self.\u srcHost,srcPath,basePath,dstPath)raw_string=r'/usr/bin/rsync-e/usr/bin/ssh-o BatchMode=yes-o UserKnownHostsFile=%s/%s/%s@%s:%s:%s(basePath,self.\u known hostspathname,basePath,self.\u certPathName,self.\u srcUser,self.\u srcHost,srcPath,basePath,dstPath)非常感谢您的帮助Joao,但是:我一直在获取“命令行0:行尾垃圾”。在从Python调用该命令之前,该命令在您的shell中真的有效吗?我不确定您是否是一个)成功访问已知的_hosts文件b)成功地在两个主机之间预先建立了一个ssh隧道,当路径名中有空格时,它在Python中工作。使用列表而不是压缩字符串为我解决了许多引用/转义问题,这里没有提到这些问题。谢谢