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
.)