scp doesn't work but ssh does

60

21

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?

scdmb

Posted 2012-02-29T15:44:22.230

Reputation: 821

You might try scp to a different location on the server, then a cp or mv after ssh – Jesse W. Collins – 2019-05-29T19:36:05.940

Provide more information such as the operating system, ssh config file, etc. – qroberts – 2012-02-29T16:11:09.160

And what are these three lines that are printed? – jjlin – 2012-02-29T17:05:18.673

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 – 2012-03-01T19:53:44.773

3Can you provide the output when you run "scp -v file server:". – dan_linder – 2012-03-01T19:54:24.867

Answers

72

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 jf@otherserver.com tar xzf - -C ~/saved_tree

to send it over, and

ssh jf@otherserver.com "tar czf - ~/saved_tree" | tar xzvf - -C ./

to get it back.

faitjx

Posted 2012-02-29T15:44:22.230

Reputation: 736

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 – 2017-06-18T15:00:11.263

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. – Tyler Abair – 2017-10-06T17:33:36.777

I basically removed "zsh" from my .bashrc on the remote server and scp started working! – Geek – 2018-03-17T00:11:32.630

It also breaks if you alter the SHELL variable (e.g. export SHELL=/bin/zsh) in ~/.bashrc. This is sometimes being used in absence of chsh. – Suuuehgi – 2018-04-23T11:35:54.613

Thanks. I had to remove command="cd <path to default dir>; /bin/bash -l" in the authorized_keys file in the server's .ssh directory – Waruna Ranasinghe – 2018-06-26T15:09:58.713

I was printing a message using echo in ~/.bashrc. After removing it, scp works again. – nio – 2018-07-24T08:06:51.173

@Alexandros, you can use the logic in this answer to skip ~/.bashrc when non-interactive (which is the case for scp).

– wisbucky – 2019-09-16T23:42:29.733

Totally works. My MOTD printed from bashrc broke scp. – Mike – 2020-02-19T18:03:30.673

61

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.

spoulson

Posted 2012-02-29T15:44:22.230

Reputation: 1 420

4If 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 – 2016-05-15T09:05:47.733

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 – 2019-09-16T23:47:59.683

15

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

scp test.txt username@remoteserver.com

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 username@remoteserver.com:~/

Example usages:

Send a file:

scp /path/to/local/file yourremoteusername@servername.com:/path/to/remote/directory

Get a file:

scp yourremoteusername@servername.com:/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 john_doe@10.1.1.10:~/

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

Send a file to the the webroot:

scp ~/Documents/working/index.html john_doe@johndoe.com:/var/www/index.html

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

InChargeOfIT

Posted 2012-02-29T15:44:22.230

Reputation: 570

2you 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 – 2012-02-29T18:14:00.477

@akira maybe, maybe not. Not providing valid paths will cause the scp command to fail.. e.g, scp somefile user@host.com: Also, not having the correct permissions on the remote directory would also cause problems. Edited my answer to make it a little clearer – InChargeOfIT – 2012-02-29T18:17:57.090

1none of your examples cover "file does not exist", none of your examples cover "permissions wrong on server side"... – akira – 2012-02-29T18:29:45.980

5

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.

frederickjh

Posted 2012-02-29T15:44:22.230

Reputation: 548

0

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.

anarchist912

Posted 2012-02-29T15:44:22.230

Reputation: 111

0

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

Removing this solved the problem for me.

dips

Posted 2012-02-29T15:44:22.230

Reputation: 101