90

If I want to send something via scp to server:

scp file server:
                   _____  _____  _____

Then three lines are printed and file is not copied. However I can connect to server via ssh without problem:

ssh server

How to make scp work?

6
  • Provide more information such as the operating system, ssh config file, etc.
    – qroberts
    Feb 29, 2012 at 16:11
  • And what are these three lines that are printed?
    – jjlin
    Feb 29, 2012 at 17:05
  • In the normal case, when you run scp file server: (assuming "server" is a valid hostname), the file is copied to your account directory.
    – dan_linder
    Mar 1, 2012 at 19:53
  • 3
    Can you provide the output when you run "scp -v file server:".
    – dan_linder
    Mar 1, 2012 at 19:54
  • You might try scp to a different location on the server, then a cp or mv after ssh May 29, 2019 at 19:36

9 Answers 9

105

One possible cause of this type of behavior is having any message print out during the login process on server. Scp depends on ssh to provide a totally transparent encrypted tunnel between the client and the server.

Check all of the login scripts on the server, and also try using a different user. Another method of identifying the source of the error is to use the -v in the command, to trace the progress of the transaction, and see where it fails. You can use up to -vvv to increase the verbosity, if necessary. Checking the various forms of scp can also be instructive, as listed in the post by InChargeOfIT.

scp, under the hood, sets up a tunnel using ssh, and then transfers the file over that tunnel, with a ssh command on the far end to catch the file as it comes over. This is illustrated by the use of tar and ssh to copy a directory structure preserving ownership and creation times with the following commands:

tar czf - ./* | ssh [email protected] tar xzf - -C ~/saved_tree

to send it over, and

ssh [email protected] "tar czf - ~/saved_tree" | tar xzvf - -C ./

to get it back.

10
  • 2
    Is it possible to detect scp within .bashrc? So that you can check and only print output when the shell is not an scp one?
    – Alexandros
    Jun 18, 2017 at 15:00
  • The user also needs to be privilege level 15. If the user is not privilege level 15, the ASA will just close the connection after authentication with no error message indicating a privilege issue. Also, just because your user can type enable and enter a password doesn't mean they're priv 15. If you don't see "privilege 15" somewhere in show run | inc USERNAME then they won't be able to scp. Oct 6, 2017 at 17:33
  • 1
    I basically removed "zsh" from my .bashrc on the remote server and scp started working!
    – Geek
    Mar 17, 2018 at 0:11
  • 2
    I was printing a message using echo in ~/.bashrc. After removing it, scp works again.
    – nio
    Jul 24, 2018 at 8:06
  • 4
    Totally works. My MOTD printed from bashrc broke scp.
    – Mike
    Feb 19, 2020 at 18:03
79

Check the target user's .bashrc or equivalent file. ~/.bashrc is sourced for non-interactive logins.

If there's an echo or command that outputs anything, it will break the SCP protocol.

4
  • 10
    If you still want your fortune | cowsay, just put it in .bash_profile. That's for interactive only logins and should not be sourced during the SCP session.
    – spoulson
    May 15, 2016 at 9:05
  • My problem was I was sourcing another file in my .bashrc, which would not exist on the other machine. You can use the logic in this answer to skip ~/.bashrc when non-interactive (which is the case for scp).
    – wisbucky
    Sep 16, 2019 at 23:47
  • I had an echo command in /etc/ssh/sshrc which caused the same problem
    – 5p0ng3b0b
    Sep 7, 2021 at 12:33
  • WOW this has just saved a life.
    – Dyin
    Nov 19, 2022 at 19:45
26

Are you positive you are entering in a valid path in the scp command? For example:

scp test.txt [email protected]

will fail (in fact, it will just print out the command like you are seeing). In this case, you will need to provide a valid path to the remote server.. e.g., scp test.txt [email protected]:~/

Example usages:

Send a file:

scp /path/to/local/file [email protected]:/path/to/remote/directory

Get a file:

scp [email protected]:/path/to/remote/file /path/to/local/directory

Examples:

Send a file from my Desktop to my home folder on a remote server:

scp ~/Desktop/myfile.txt [email protected]:~/

Remember the ~ is a shortcut for your home directory... e.g., /home/

Send a file to the the webroot:

scp ~/Documents/working/index.html [email protected]:/var/www/index.html

In this example, the user john_doe would need write privileges on the remote /var/www directory.

4
  • 3
    you are not answering the question. the commandline given by OP looks fairly ok, the interesting part are the ------ ... none of your examples relates to that.
    – akira
    Feb 29, 2012 at 18:14
  • @akira maybe, maybe not. Not providing valid paths will cause the scp command to fail.. e.g, scp somefile [email protected]: Also, not having the correct permissions on the remote directory would also cause problems. Edited my answer to make it a little clearer Feb 29, 2012 at 18:17
  • 1
    none of your examples cover "file does not exist", none of your examples cover "permissions wrong on server side"...
    – akira
    Feb 29, 2012 at 18:29
  • I don't believe you need the "~/" after the colon as the default is already your home directory. That said, it doesn't hurt. Jul 8, 2020 at 17:20
12

On some hosts they incorrectly source .bash_profile for non-interactive logins like scp. Messages that get printed to the terminal can possibly cause scp to not function correctly. If you have messages in your .bash_profile this can be the cause.

To still have your login messages, banner, etc. display on interactive logins and still be able to use scp via a non-interactive login add the following before any message that would print out in your .bash_profile file.

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

[ -z "$PS1" ] && return

Alternative code is:

[[ $- == *i* ]] || return

And another alternative code:

case $- in
    *i*) ;;
      *) return;;
esac

Which I believe is the longer version of the first alternative code. I have found on some hosts the first code does not work correctly but the second one does.

During a non-interactive scp login it will abort further execution of .bash_profile and allow scp to work, but will display your login messages when you login via ssh.

Note: This can also be used in your .bashrc file if you source it from .bash_profile (for $PATH) so only part of it is sourced during non-interactive logins.

3
  • This answer really work.
    – Jim Chen
    Jan 14, 2021 at 2:44
  • I had some echo msg in ~/.ssh/rc and it was breaking SCP. So yes, don't print to non-interactive sessions.
    – A.D.
    Feb 21, 2021 at 15:09
  • For me, it worked after putting it at the beginning of .bashrc, while it did not work if put into .bash_profile
    – Daniele
    Apr 5, 2022 at 16:49
9

If you just upgraded your client, you may want to check if the -O option is relevant. I just upgraded my Cygwin, and the scp client changed to using the newer SFTP protocol by default, which usually works fine but fails badly for one of the old servers we still have running:

    -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.

Even verbose debugging told me nothing useful except that there were no overt errors, but adding -O to the command line corrected the problem:

scp -O [email protected]:file\* .

The verbose output (below) might indicate that somewhere, but my knowledge of the protocol isn't quite good enough to interpret the packets :)

    bash$ scp -vvvv [email protected]: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
    [email protected]'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$ 
2
  • Thanks! The clue I should have noticed is that the scp -v output included "debug1: Sending subsystem: sftp subsystem request failed on channel 0" Sep 28, 2022 at 16:06
  • Thanks, also the case for ish on e.g iPhone/iPad so arguable modern systems but relying on busybox which tends to rely on legacy protocols.
    – Utopiah
    May 8, 2023 at 13:08
3

I was calling exec /bin/bash in .cshrc.

Removing this solved the problem for me.

1
  • 1
    This solved it for me
    – Elad Avron
    Oct 26, 2020 at 8:30
2

When troubleshooting ssh/scp, it's a good idea to add the -v option for verbose output. You may also want to specific the user on the remote server. Lastly, it is sometimes helpful to copy the file to a temporary place such as /tmp where you know you have write permissions. For example, to send a hello world file to the remote server with verbose on, the syntax would be:

scp -v hello_world.txt username@server-uri:/tmp

Replace username with a user that exists on that system and of course replace the server-uri with the actual server FQDN or IP Address.

1

This does not answer the question directly, but might be helpful for folks like me, looking for a solution with a freezing scp when transferring files between 2 remote hosts.

If scp hangs because of messages from ssh, it could helpt to surpress them:

scp -o "StrictHostKeyChecking no"

and / or

scp -B

From the scp man:

-B Selects batch mode (prevents asking for passwords or passphrases).

-o ssh_option Can be used to pass options to ssh in the format used in there is no separate scp command-line flag. For full details of the options listed below, and their possible values, see ssh_config(5).

In my case that seemed to help, but did not solve the whole issue. We could not find out why scp hangs when transferring from remote to remote. It hung in the middle of the file. 9 times it worked, attempt number 10 did not. We suspected it could be that it hangs when our VPN connection gets a traffic spike for a moment and then scp does not recover. It really just hangs forever and does not even give an error message.

However, I gave up and switched to sftp. This is reasonably faster, as it uses a direct connection between the remote hosts. You have to enable

Host example.com
    AgentForward yes

in the ~/.shh/config file of the machine that is running the script though. Of course this is only a solution if the remote machines are both within your trusted network.

0

One reason scp can fail, even when ssh works, is that the port number needs to be specified before the host. I don't know why. But this is wrong:

scp pi@localhost:/home/pi/paula-bean -P 3022 /mnt/home/

instead, it should be

scp -P 3022 pi@localhost:/home/pi/paula-bean /mnt/home/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .