scp 不起作用,但 ssh 起作用

scd*_*dmb 75 ssh scp

如果我想通过 scp 向服务器发送一些东西:

$ scp file server:
                   _____  _____  _____
$
Run Code Online (Sandbox Code Playgroud)

,然后打印三行并且不复制文件。但是我可以毫无问题地通过 ssh 连接到服务器:

$ ssh server
Run Code Online (Sandbox Code Playgroud)

如何使 scp 工作?

小智 92

此类行为的一个可能原因是在服务器上的登录过程中打印出任何消息。scp 依赖 ssh 在客户端和服务器之间提供一个完全透明的加密隧道。

检查服务器上的所有登录脚本,并尝试使用其他用户。识别错误来源的另一种方法是在命令中使用 -v 来跟踪事务的进度,并查看失败的地方。如有必要,您最多可以使用 -vvv 来增加详细程度。检查各种形式的 scp 也很有启发性,如 InChargeOfIT 的帖子中所列。

scp 在幕后使用 ssh 建立一个隧道,然后通过该隧道传输文件,在远端使用 ssh 命令捕获文件。这通过使用 tar 和 ssh 通过以下命令复制保留所有权和创建时间的目录结构来说明:

  tar czf - ./* | ssh jf@otherserver.com tar xzf - -C ~/saved_tree
Run Code Online (Sandbox Code Playgroud)

发送它,和

ssh jf@otherserver.com "tar czf - ~/saved_tree" | tar xzvf - -C ./
Run Code Online (Sandbox Code Playgroud)

把它拿回来。

  • 完全有效。我从 bashrc 打印的 MOTD 破坏了 scp。 (3认同)
  • 是否可以在 .bashrc 中检测到 scp?这样您就可以检查并仅在 shell 不是 scp 时打印输出? (2认同)
  • 我在 ~/.bashrc 中使用 echo 打印一条消息。删除它后, scp 再次工作。 (2认同)

spo*_*son 71

检查目标用户的 .bashrc 或等效文件。~/.bashrc 用于非交互式登录。如果有输出任何内容的回声或命令,它将破坏 SCP 协议。

  • 如果你还想要你的`财富| cowsay`,只需将其放在 .bash_profile 中即可。这仅用于交互式登录,不应在 SCP 会话期间获取。 (9认同)

InC*_*fIT 23

编辑:您确定您在 scp 命令中输入了有效路径吗?例如:

scp test.txt username@remoteserver.com
Run Code Online (Sandbox Code Playgroud)

将失败(实际上,它只会像您看到的那样打印出命令)。在这种情况下,您需要提供远程服务器的有效路径.. 例如,scp test.txt username@remoteserver.com:~/

示例用法:

发送文件:

scp /path/to/local/file yourremoteusername@servername.com:/path/to/remote/directory
Run Code Online (Sandbox Code Playgroud)

获取文件:

scp yourremoteusername@servername.com:/path/to/remote/file /path/to/local/directory
Run Code Online (Sandbox Code Playgroud)

例子:

将文件从我的桌面发送到远程服务器上的主文件夹:

scp ~/Desktop/myfile.txt john_doe@10.1.1.10:~/
Run Code Online (Sandbox Code Playgroud)

请记住,这~是您的主目录的快捷方式...例如,/home/

将文件发送到 webroot:

scp ~/Documents/working/index.html john_doe@johndoe.com:/var/www/index.html
Run Code Online (Sandbox Code Playgroud)

在此示例中,用户 john_doe 将需要对远程 /var/www 目录的写权限。

  • 你不是在回答这个问题。OP 给出的命令行看起来还不错,有趣的部分是 `------` ......你的例子都没有与此相关。 (2认同)

fre*_*kjh 11

在某些主机上,它们错误地.bash_profile为非交互式登录(如 scp)提供源。打印到终端的消息可能会导致scp无法正常运行。如果您有消息,.bash_profile这可能是原因。

要在交互式登录中仍然显示您的登录消息、横幅等,并且仍然能够scp通过非交互式登录使用,请在将打印在您的.bash_profile文件中的任何消息之前添加以下内容。

# ********** If not running interactively, don't do anything more! ***********

[ -z "$PS1" ] && return
Run Code Online (Sandbox Code Playgroud)

替代代码是:

[[ $- == *i* ]] || return
Run Code Online (Sandbox Code Playgroud)

另一个替代代码:

case $- in
    *i*) ;;
      *) return;;
esac
Run Code Online (Sandbox Code Playgroud)

我相信这是第一个替代代码的较长版本。我发现在某些主机上,第一个代码无法正常工作,但第二个代码可以。

在非交互式 scp 登录期间,它将中止 .bash_profile 的进一步执行并允许 scp 工作,但会在您通过 ssh 登录时显示您的登录消息。

注意:.bashrc如果您从.bash_profile(对于 $PATH)获取它,也可以在您的文件中使用它,因此在非交互式登录期间仅获取其中的一部分。


小智 9

如果您刚刚升级了客户端,您可能需要检查该-O选项是否相关。我刚刚升级了 Cygwin,默认情况下 scp 客户端更改为使用较新的 SFTP 协议,该协议通常工作正常,但对于我们仍在运行的旧服务器之一来说会严重失败:

    -O    Use the legacy SCP protocol for file transfers instead of the SFTP
          protocol. Forcing the use of the SCP protocol may be necessary for 
          servers that do not implement SFTP, for backwards-compatibility for 
          particular filename wildcard patterns and for expanding paths with 
          a '~' prefix for older SFTP servers.
Run Code Online (Sandbox Code Playgroud)

即使是详细的调试也没有告诉我任何有用的信息,除了没有明显的错误,但添加-O到命令行可以纠正问题:

scp -O user@host.net:file\* .
Run Code Online (Sandbox Code Playgroud)

详细的输出(如下)可能表明某个地方,但我对协议的了解还不足以解释数据包:)

    bash$ scp -vvvv user@host.net:file\* .
    Executing: program /usr/bin/ssh host host.net, user user, command sftp
    OpenSSH_9.0p1, OpenSSL 1.1.1p  21 Jun 2022
        ...
    debug1: Authentications that can continue: publickey,keyboard-interactive,password
    debug3: userauth_kbdint: disable: no info_req_seen
    debug2: we did not send a packet, disable method
    debug3: authmethod_lookup password
    debug3: remaining preferred:
    debug3: authmethod_is_enabled password
    debug1: Next authentication method: password
    user@host.net's password:
    debug3: send packet: type 50
    debug2: we sent a password packet, wait for reply
    debug3: receive packet: type 52
    Authenticated to host.net ([192.168.1.32]:22) using "password".
    debug1: channel 0: new [client-session]
    debug3: ssh_session2_open: channel_new: 0
    debug2: channel 0: send open
    debug3: send packet: type 90
    debug1: Entering interactive session.
    debug1: pledge: filesystem
    debug3: receive packet: type 91
    debug2: channel_input_open_confirmation: channel 0: callback start
    debug2: fd 4 setting TCP_NODELAY
    debug3: set_sock_tos: set socket 4 IP_TOS 0x20
    debug2: client_session2_setup: id 0
    debug1: Sending subsystem: sftp
    debug2: channel 0: request subsystem confirm 1
    debug3: send packet: type 98
    debug2: channel_input_open_confirmation: channel 0: callback done
    debug2: channel 0: open confirm rwindow 0 rmax 16384
    debug2: channel 0: rcvd adjust 32768
    debug3: receive packet: type 99
    debug2: channel_input_status_confirm: type 99 id 0
    debug2: subsystem request accepted on channel 0
    debug3: receive packet: type 98
    debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
    debug3: receive packet: type 96
    debug2: channel 0: rcvd eof
    debug2: channel 0: output open -> drain
    debug2: channel 0: obuf empty
    debug2: chan_shutdown_write: channel 0: (i0 o1 sock -1 wfd 6 efd 7 [write])
    debug2: channel 0: output drain -> closed
    debug3: receive packet: type 97
    debug2: channel 0: rcvd close
    debug2: chan_shutdown_read: channel 0: (i0 o3 sock -1 wfd 5 efd 7 [write])
    scp: Connection closed
    debug2: channel 0: input open -> closed
    debug3: channel 0: will not send data after close
    debug2: channel 0: almost dead
    debug2: channel 0: gc: notify user
    debug2: channel 0: gc: user detached
    debug2: channel 0: send close
    debug3: send packet: type 97
    debug2: channel 0: is dead
    debug2: channel 0: garbage collecting
    debug1: channel 0: free: client-session, nchannels 1
    debug3: channel 0: status: The following connections are open:
      #0 client-session (t4 r0 i3/0 o3/0 e[write]/0 fd -1/-1/7 sock -1 cc -1 io 0x00/0x00)

    debug3: send packet: type 1
    Transferred: sent 1960, received 1512 bytes, in 0.2 seconds
    Bytes per second: sent 11090.3, received 8555.4
    debug1: Exit status 1
    bash$ 
Run Code Online (Sandbox Code Playgroud)