While trying to back up my personal data using
rsync -aruvzh --delete /home/thanassis/jdevhome/ firstname.lastname@example.org:/home/thanassis/jdevhome I run into the following error message.
protocol version mismatch - is your shell clean? (see the rsync man page for an explanation) rsync error: protocol incompatibility (code 2) at compat.c(69)
A little googling and a final look at the rsync manual revealed that :
DIAGNOSTICS rsync occasionally produces error messages that may seem a little cryp- tic. The one that seems to cause the most confusion is “protocol ver- sion mismatch — is your shell clean?”. This message is usually caused by your startup scripts or remote shell facility producing unwanted garbage on the stream that rsync is using for its transport. The way to diagnose this problem is to run your remote shell like this: ssh remotehost /bin/true > out.dat then look at out.dat. If everything is working correctly then out.dat should be a zero length file. If you are getting the above error from rsync then you will probably find that out.dat contains some text or data. Look at the contents and try to work out what is producing it. The most common cause is incorrectly configured shell startup scripts (such as .cshrc or .profile) that contain output statements for non- interactive logins.
Needless to say that fortune was the one to blame. My .bashrc file had the following last statements since the days of SuSE 8.2 and although I am now using a completely different distro, I still refuse to get them out of my startup files.
# Something to remember the old SuSE days if [ -x /usr/bin/fortune ] ; then echo /usr/bin/fortune echo fi
So, the solution would be to display a fortune cookie only when the current shell is interactive and then it was time for the Bash Reference Manual to come to our rescue. Their answers are straightforward :
To determine within a startup script whether Bash is running interactively or not, examine the variable $PS1; it is unset in non-interactive shells, and set in interactive shells. Thus:
if [ -z "$PS1" ]; then echo This shell is not interactive else echo This shell is interactive fi
Alternatively, startup scripts may test the value of the `-' special parameter. It contains i when the shell is interactive. For example:
case "$-" in *i*) echo This shell is interactive ;; *) echo This shell is not interactive ;; esac
In my case I wanted to run fortune on interactive shells only. So again I modified my bashrc file to look like :
# Display a fortune cookie on interactive logins only if [ -n "$PS1" ]; then # Some people don't like fortune. If you uncomment the following lines, # you will have a fortune each time you log in ;-) if [ -x /usr/bin/fortune ] ; then echo /usr/bin/fortune echo fi fi
... and that did it.