Bash Tips: SCP Compatibility
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
return
fi
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
.)