I cannot copy a file over scp when the remote machine .bashrc file includes source command to update paths and some variables. Why does it happen?

  • Is your user shell actually /bin/sh? Are you sourcing ~/.bashrc from ~/.profile? – jordanm Sep 8 '14 at 15:05
  • Yes, my bash is /bin/sh. I asked the question wrongly. My .bashrc file includes a source command to update the paths. – yildizabdullah Sep 8 '14 at 16:16
  • 1
    The problem probably is not that .bashrc is reading in other files but that it is outputting something. This will confuse scp, which actually runs ssh to run a slightly different scp command on the remote system and then parses its output. If you can rewrite your .bashrc so that nothing it runs or sources will produce output, scp will probably work. – Mark Plotnick Sep 8 '14 at 16:49
  • I know that scp runs when .bashrc does not source or run anything. I wonder if there is a workaround for that during login process. – yildizabdullah Sep 8 '14 at 16:55

You should make part or all of your .bashrc not run when your shell is non-interactive. (An scp is an example of a non-interactive shell invocation, unless someone has radically altered your systems.) Then put all commands that can possibly generate output in that section of the file.

A standard way to do this in an init file is:

# Put all the commands here that should run regardless of whether
# this is an interactive or non-interactive shell.

# Example command:
umask 0027

# test if the prompt var is not set
if [ -z "$PS1" ]; then
    # prompt var is not set, so this is *not* an interactive shell

# If we reach this line of code, then the prompt var is set, so
# this is an interactive shell.

# Put all the commands here that should run only if this is an
# interactive shell.

# Example command:
echo "Welcome, ${USER}.  This is the ~/.bashrc file."

You might also see people use

[ -z "$PS1" ] && return

instead of my more verbose if statement.

If you don't want to rearrange your whole file, you can also just make certain lines run only in interactive context by wrapping them like so:

if [ -n "$PS1" ]; then
    echo "This line only runs in interactive mode."

If you segregate your .bashrc this way, then your scp commands should no longer have this problem.

| improve this answer | |
  • 1
    Good advice. This problem has been around for over 30 years, dating from BSD's rcp command coupled with csh and .cshrc. Hopefully, in time, ssh can provide an alternative way of doing scp that isn't affected by the remote user's shell at all. – Mark Plotnick Sep 8 '14 at 17:58
  • It is very informative! It's the answer that I'm looking for. – yildizabdullah Sep 8 '14 at 19:23
  • I had this issue; but needed to return (versus exit). When I used exit the scp didn't output; but also didn't copy files. – Raymond Kroeker Aug 16 '15 at 18:14
  • Your solution did not work for me (specifically in the case of resuming gnu screen), but this did: commandlinefu.com/commands/view/13589/… [ "$TERM" != "dumb" ] && [ -z "$STY" ] && screen -DRA – fbas Jan 28 at 14:16
  • This explains what the problem is and how to fix it, but I'd love to know why it fails. What about putting an interactive command (e.g. source or echo) in a ~/.bashrc file causes SCP to fail? – jvriesem Mar 30 at 18:59

This solution worked for me as well. But since my default shell is TCSH, I had to slightly edit the fix as follows (in .tcshrc):

if ( $?SSH_TTY ) then
    exec /bin/bash

Just thought I would share for everyone's benefit.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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