让 scp 表现得像它应该的那样(远程文件复制程序)

让 scp 表现得像它应该的那样(远程文件复制程序)

我想使用将本地文件复制到远程服务器scp

scp -rp local-file my.server.com:/tmp/

有时我忘记指定文件应复制到远程服务器上的位置:

scp -rp local-file my.server.com

或者,有时我输错:;

scp -rp local-file my.server.com;/tmp/

在这两种情况下,scp都应该失败。但相反,它的行为完全愚蠢,并在本地复制本地文件,就像cp会做的那样。

cp local-file my.server.com

甚至man scpscpremote file copy program。那么为什么它会默默地失败,并且表现得像cp

有任何解决这个问题的方法吗 ?

我的版本openssh-client1:6.0p1-4+deb7u6

答案1

在 bash 中,您可以编写这样的包装函数。

function scp { 
  if grep -q ':[^ $]' <<< "$*" ; then
    command "${FUNCNAME[0]}" "$@"
  else
    echo "missing or invalid hostname:path in scp command"
    return 1
  fi
}

这是一个非常粗略的示例,它所做的只是检查:命令行中是否有一个后跟至少一个非空格字符(这对于概念验证示例来说足够好,但不足以用于实际使用)。如果有,它将运行该scp命令。如果不是,它会打印一条错误消息并返回退出代码 1。

或者您可以将其编写为脚本 - 无论哪种方式都没有什么区别。

顺便说一句,我上面说“在 bash 中”,那是因为我只在 bash 中测试了上述函数。这并不意味着只有 bash 可以做到这一点。大多数其他 sh 实现允许您执行相同或类似的操作。语法可能略有不同,并且您可能必须进行硬编码command scp ...而不是更通用的command "${FUNCNAME[0]} ...".

PS:我不判断 scp 是否“应该”这样做。这由您决定自己的系统。然而,当您必须在没有所有自定义黑客/拐杖的系统上工作时,对此类东西的依赖会让您处于严重的劣势。

答案2

简短的回答是你不能。

请注意,man scp提及远程主机作为可选:

scp(已删除 scp 选项) [[user@]host1:]file1 ... [[user@]host2:]file2

现在,当您发出命令时

scp arg1 arg2

scp将通过查找:inarg1或 来决定远程主机在哪里arg2(并且可能允许两个远程主机(solaris、ubuntu),但情况并非总是如此)。

如果既没有arg1,也arg2没有冒号,则scp只需按cp

答案3

除了其他答案之外,请注意这scp不是一个单独的协议本身,但只是较旧的rcp用于ssh传输而不是未加密的TCP。它的目的是作为一种直接替代方案,任何脚本化或非脚本化rcp都可以被更安全的替代,scp而无需任何更改。并rcp允许通过解析:.

答案4

虽然它被称为远程文件复制程序,但我认为它的设计目的是能够满足本地复制需求以及远程需求。测试时,这种行为也反映在我的环境中。

还值得注意的是,当从环境变量 $? 检索值时在本地运行后,观察到返回码为 0。这表明它的行为符合预期,并且没有输出错误代码。

不幸的是,我不确定是否存在解决此默认行为的方法。使用其他工具可能是唯一的选择。

相关内容