【问题标题】:How to scp a directory with a space in the name [duplicate]如何scp名称中带有空格的目录[重复]
【发布时间】:2016-02-27 10:56:20
【问题描述】:

我现在正在尝试将整个目录从一个集群镜像复制到另一个集群。但是当名称中有空格时它会失败,我无法弄清楚如何解决这个问题,因为似乎 scp 认为我正在复制多个文件。我正在使用一个变量来标记我需要的路径,因此添加反斜杠似乎不容易解决。

这是我正在使用的代码:

if ssh user@ip -i key test -d "'$current_dir'"; then
 echo "Directory exists. Ready to copy $dir_name."
 scp -i key -r "$current_dir/$dir_name" user@$ip:"$current_dir/$dir_name"
else
 echo Directory doesn\'t exist. Making a new directory.
 ssh user@$ip -i key mkdir "'$current_dir'"
 scp -i key -r "$current_dir/$dir_name" user@$ip:"$current_dir/$dir_name"
fi

我尝试过单引号、双引号和带双引号的单引号,但它们都不起作用。任何人都可以帮我解决它吗?顺便说一句,代码中的 mkdir 语句有效。

【问题讨论】:

  • 这到底是哪一部分失败了? $current_dir 的值是多少?你到底得到了什么错误?
  • 嘿伊坦。 $current_dir 是存储从pwd 返回的路径的变量。并且错误说 scp ambiguous target。
  • 显示失败的$current_dir 的准确错误和准确值。您可以使用 set -x 让 shell 打印出它在运行时将执行的确切命令。
  • 设置-x后显示没有这样的文件或目录,这是合理的,因为当目录名中有空格时,scp可能会将一个目录视为两个文件。
  • 你错过了我评论中的 show 部分。 显示 set -x 和准确的错误输出。您可能非常需要转义或额外引用文件名中的空格,以便它们通过 scp 但没有看到发生了什么我不能确定我什至知道问题是什么。

标签: bash scp


【解决方案1】:

您可以使用 sed 转义目录名称中的空格:

current_dir = "/usr/bin/Directory With Spaces"
escaped_current_dir = `sed s/ /\\ /g $current_dir`
# escaped_current_dir = "/usr/bin/Directory\ With\ Spaces"

带有转义空格的字符串将被读取为一个字符串,并且只有一个字符串,这是我们想要的。

【讨论】:

    【解决方案2】:

    您需要将字段分隔符设置为空格。

    OIFS=$IFS  #save the original
    IFS=$"\ "  #set to space
    current_dir="some dir with spaces"
    scp_current_dir="some\\ dir\\ with\\ spaces"
    dir_name="another dir with spaces"
    scp_dir_name="another\\ dir\\ with\\ spaces"
    if ssh user@ip -i key test -d $current_dir; then
     echo "Directory exists. Ready to copy $dir_name."
     scp -i key -r "$current_dir/$dir_name" user@$ip:"$scp_current_dir/$scp_dir_name"
    else
     echo Directory doesn\'t exist. Making a new directory.
     ssh user@$ip -i key mkdir $current_dir
     scp -i key -r "$current_dir/$dir_name" user@$ip:"$scp_current_dir/$scp_dir_name"
    fi
    IFS=$OIFS  #reset it back to the original
    

    【讨论】:

    • 我想知道为什么投反对票?解决方案有问题吗?如果是,有更好的解决方案吗?
    • (不是我的投票。)这有什么帮助?这会将IFS 设置在本地,但引用完全避免了基于IFS 的拆分。估计是远端有问题。
    • 嗨科达。我不知道是谁投了反对票,但是我尝试了您的解决方案,但没有成功。仍然得到与 scp ambiguous target 相同的错误。
    • @Jonas 这是您正在使用的整个脚本吗?设置 IFS 应该有助于空格。如果您发布整个脚本,我可以尝试看看发生了什么。
    • @Jonas 我稍微修正了脚本。现在IFS=$"\ "。这可能是它对您不起作用的原因。立即尝试。
    【解决方案3】:

    作为detailed in this answer,您需要使用两组引号,因为文件名被解释两次:一次由本地计算机解释,一次由远程计算机解释。

    scp -i key -r "$current_dir/$dir_name" user@$ip:"'$current_dir/$dir_name'"
    

    【讨论】:

    • 是的,成功了!!!谢谢迈肯。我真的应该弄清楚如何很好地使用 stalkoverflow。谷歌没有给我这个答案。不管怎样,谢谢!感恩节快乐。
    • 如何知道另一端将使用什么外壳,以便知道应用内引用的引用语法?这种方法是否应该只用在脚本作者可以控制另一端的 shell 的脚本中?
    • @codeshot 非常好的问题,是的,您确实需要知道另一端正在运行什么外壳(尽管除非它像 Windows 那样令人憎恶,我认为您可以假设 sh 引用) .
    • @codeshot 我不知道有任何 shell 将标识符用单引号括起来不会将空格与 shell 隔离,但是 - 如果存在这样的事情 - 那么是的:你会有对此进行调整。
    猜你喜欢
    • 2012-08-15
    • 2019-04-02
    • 2013-08-21
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 2019-04-10
    相关资源
    最近更新 更多