Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've been experiencing very strange behavior of SCP for some time: whenever I try to copy a file, the output of SCP contains a bunch of underscores and the file is not copied.

$ scp test.txt 192.168.0.2:~
job@192.168.0.2's password: 
 ________________________________________

When I create an SSH connection using Midnight Commander and copy files it does work.

Some info about my machine:

$ ssh -V
OpenSSH_5.8p1 Debian-1ubuntu3, OpenSSL 0.9.8o 01 Jun 2010

$ uname -a
Linux squatpc 2.6.38-10-generic #46-Ubuntu SMP Tue Jun 28 15:05:41 UTC 2011 i686 i686 i386 GNU/Linux

And I'm running Kubuntu 11.04.

Edit: Some more info as requested by the comments:

$ scp -v test.txt 192.168.0.2:~
Executing: program /usr/bin/ssh host 192.168.0.2, user (unspecified), command scp -v -t -- ~
OpenSSH_5.8p1 Debian-1ubuntu3, OpenSSL 0.9.8o 01 Jun 2010
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to 192.168.0.2 [192.168.0.2] port 22.
debug1: Connection established.
debug1: identity file /home/job/.ssh/id_rsa type 1
debug1: Checking blacklist file /usr/share/ssh/blacklist.RSA-2048
debug1: Checking blacklist file /etc/ssh/blacklist.RSA-2048
debug1: identity file /home/job/.ssh/id_rsa-cert type -1
debug1: identity file /home/job/.ssh/id_dsa type -1
debug1: identity file /home/job/.ssh/id_dsa-cert type -1
debug1: identity file /home/job/.ssh/id_ecdsa type -1
debug1: identity file /home/job/.ssh/id_ecdsa-cert type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.8p1 Debian-1ubuntu3
debug1: match: OpenSSH_5.8p1 Debian-1ubuntu3 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.8p1 Debian-1ubuntu3
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: sending SSH2_MSG_KEX_ECDH_INIT
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ECDSA 28:f3:2b:31:36:43:9b:07:d8:33:ca:43:4f:ca:6c:4c
debug1: Host '192.168.0.2' is known and matches the ECDSA host key.
debug1: Found key in /home/job/.ssh/known_hosts:20
debug1: ssh_ecdsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/job/.ssh/id_rsa
debug1: Authentications that can continue: publickey,password
debug1: Trying private key: /home/job/.ssh/id_dsa
debug1: Trying private key: /home/job/.ssh/id_ecdsa
debug1: Next authentication method: password
job@192.168.0.2's password: 
debug1: Authentication succeeded (password).
Authenticated to 192.168.0.2 ([192.168.0.2]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending command: scp -v -t -- ~
 ________________________________________
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK
Transferred: sent 2120, received 1872 bytes, in 0.3 seconds
Bytes per second: sent 7783.1, received 6872.6
debug1: Exit status 0

and

$ type scp
scp is hashed (/usr/bin/scp)
share|improve this question
    
Try with -v to get some debugging info during the copy. –  EightBitTony Aug 7 '11 at 12:35
    
Also, just in case... What is the output of type scp? –  rozcietrzewiacz Aug 7 '11 at 13:10
    
@EightBitTony: see my edits. –  Job Aug 7 '11 at 14:28
    
@rozcietrzewiacz: see my edits too:-) –  Job Aug 7 '11 at 14:29
1  
If you do ssh 192.168.0.2 echo hello, do you get any output other than hello? –  Gilles Aug 7 '11 at 19:48

2 Answers 2

up vote 14 down vote accepted

Ok LOL, I just figured out what the problem is.

Since I like cows so much, I've put fortune | cowsay at the top of my .bashrc file which produces output like the following when starting bash:

 _______________________________________
< You will lose an important disk file. >
 ---------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

This is all fine (and sometimes funny) when running bash interactively. However, bash reads ~/.bashrc when it is interactive and not a login shell, or when it is a login shell and its parent process is rshd or sshd. When you run scp, the server starts a shell which starts a remote scp instance. The output from .bashrc confuses scp because it is sent the same way the scp protocol data is sent. This is apparently a known bug, see here for more details.

Also note that the underscores I mentioned in the question are those in the top line of the text balloon.

So the solution was simple: I put the following at the top of .bashrc:

# If not running interactively, don't do anything
[[ $- == *i* ]] || return

This line is present in the default .bashrc but was put way down because of my many (apparently careless) edits.

share|improve this answer
    
echo "don't have a cow" | cowsay –  Stéphane Gimenez Aug 12 '11 at 17:22
    
I know this test for PS1 is mentioned in a lot of places, but it's not very accurate. A better test for interactive shells is the -i option: if [[ $- != *-* ]]; then return;; fi. –  Gilles Aug 12 '11 at 23:13
    
@Gilles: Bash mentions this method in its man page: "PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state." So I guess it should be accurate. –  Job Aug 13 '11 at 14:37
1  
@Job PS1 can be set even if the shell is not interactive. So no, it's not accurate, unlike $-. Even $- has false positives sometimes, because the shell is technically interactive but it's in fact talking through a terminal but to a program rather than a human. But at least $- accurately tells you whether the shell is talking to a terminal. –  Gilles Aug 13 '11 at 14:45
    
@Gilles: Ok I see. I edited my answer to make the test more accurate. –  Job Aug 13 '11 at 15:02

AFAIK, the right way to enable un-hindered scp is less about which conditional for stdout in your ~/.bashrc script, and more about simply restricting screen output to the ~/.bash_profile script. At least that is how it works for my distro (CentOS.)

Edit for clarity:

  1. Put only lines in your ~/.bashrc file as required by "all" remote conections (i.e. setting certain ENV vars is OK, but echoing human-readable text is not.)
  2. YMMV
share|improve this answer
    
mind expounding? i.e. how to restrict screen output to the .bash-profile ? –  javadba Jul 7 at 3:31
    
By screen output, I mean echo "Greetings, Master" or anything else that displays output to the terminal window. Don't put that in your ~/.bashrc --keep it in your ~/.bash_profile script. –  Mark Hudson Sep 9 at 4:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.