Rsync seems incompatible with .bashrc (causes "is your shell clean?")

Solution 1:

You can run into problems if the .bashrc on the remote server outputs anything to the terminal. Rsync may not expect that and may have problems as a result.

You can fix this by removing any commands in the .bashrc that output text, or by piping any output to /dev/null.

Solution 2:

The .bashrc is really not the correct place for generating output, as it causes this kind of problem. A lot of people get away with it, though, until they try to run rsync :-)

Any desired output (and the associated logic and commands) should be moved to your .bash_profile (see, e.g., Server Fault question ".profile vs. .bash_profile vs. .bashrc" for further discussion on the differences between the files).

That way, you won't need to sacrifice getting the output when you login, nor deal with making temporary changes to your .bashrc when you want to use rsync.


Solution 3:

I've always had .bashrc files on my user accounts and never had this problem until I tried today to rsync something to my server using the root account. Your post helped me find the solution:

my $user/.bashrc files always start with the following section to prevent this kind of issue. I replicated it to root's .bashrc and rsync'ing now works like a charm!

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

HTH, karsten


Solution 4:

The problem

For complex reasons rsync/scp/sftp runs .bashrc when connecting to another host. The mere presence of .bashrc is not an issue. Problems arise if any of the commands in .bashrc produces output in a interactive session.

A good solution for most cases

Place any of these commands at the top of your .bashrc:

either

[[ $- != *i* ]] && return

or

[ -z "$PS1" ] && return

Any of the above commands will only allow the execution of the rest of .bashrc commands for interactive sessions. As far as I know you don't need them for any other type of session (and indeed I have seen default bashrc from Arch and Debian using this technique in their bashrc).

A good solution for rare cases

If you want to be extra paranoid about letting your bashrc commands run even for non interactive sessions you should at least wrap the commands that may produce output like in the example below (reference):

if shopt -q login_shell; then
    # this is an interactive session, we _can_ display output
    ...commands that may produce output goes here...
fi

A solution you should probably avoid

Others suggest moving commands that output text to your bash_profile but I have my doubts about whether this is always good (for reasons explained here)

Tags:

Bash

Rsync