Bash Tips: SCP Compatibility

Annika Backstrom
in misc, on 10 May 2004. It is tagged and #Scripting.

I've been using scp -- part of the OpenSSH package -- on a daily basis for several years now. In recent months my .bashrc files have become more complex, and at some point I started getting an annoying error message during my remote copies:

stderr is not a tty - where are you?

However charming this error message might be, I'm a little sick of seeing it. I decided to squash this one tonight, and browsing through the bash manpage and Googling did the trick.

Bash reads a wide array of configuration files on startup: ~/.bashrc is read when starting an interactive but non-login shell, ie. running bash or opening an xterm. It reads ~/.bash_profile (among others) when starting an interactive login shell, ie. logging in to a TTY in runlevel 3 or ssh'ing into a host.

To add a level of complexity to the setup, the bash run by scp runs .bashrc, though I'm not sure why. Commands in my ~/.bashrc expect stdin, stdout, and stderr to be available, but it's obvious things aren't working 100% as expected. After some searching, it turns out it's fairly simple to alter .bashrc to cooperate with scp:

# only run if we have an interactive shell
if [ $(expr index "$-" i) -eq 0 ]; then

bash gets an environment variable "$-" that contains all its startup flags. If $- contains "i", the shell is interactive. Our if checks for this flag; if the flag is not found, execution of .bashrc stops. I've put this at the top of my .bashrc for now, but at some point I will reorganize so important and non-harmful settings are still executed. (For example, $CVSROOT.)