On Fri, Jul 25, 2008 at 2:04 PM, Nuno Magalhces <[EMAIL PROTECTED]>
wrote:
...
> Yup. I didn't know why the hell was uptime being called, then i looked
> at .bashrc. Turns out scp/ssh/bash will run .bashrc and - for some
> reason - only execute the first line and then drop dead. I used an
> echo instead and had the same result: an echo, no transfer. I renamed
> it to .bashrc_ and now scp works...

Yep.  One of the circumstances under which bash will source ~/.bashrc
is when it thinks it's being run by rshd.  Some versions would also do
so when run by sshd, thus leading to problems like this.


> To, as followup questions: how do i work around this? When i'm using
> an xterminal through an ssh session i want my login shell, bash, to
> read a login script; but not scp.

There are three 'modes' for a shell: non-interactive, interactive, and login.

A shell that processes a shell script or that was passed the -c option
is non-interactive.  This includes the shell started by system(3) or
used for make(1) rules.  A POSIX compliant shell never parses any
rcfile in this mode, in part because it would make it difficult to
write reliable shell scripts.  bash will parse the file named by
$BASH_ENV in this mode if that variable is set.  You should never set
that unless you're insane.

If the shell isn't non-interactive, then it's either plain interactive
or a login shell.  If you log into the console of a machine, or via
ssh, or start xterm with the -ls option, then the shell that is
started is a login shell.  Otherwise it's a plain interactive shell.
A POSIX shell will parse ~/.profile when its a login shell, and then
the file named by $ENV when either login or interactive.  The idea is
that you put stuff that is inherited between processes, like
environment variables, into ~/.profile, while stuff that needs to be
set in each shell process, like functions, is put into your $ENV file.

Bash is different: a login shell reads a profile startup file (your
choice of three different names) and stops there, no $ENV processing,
while an interactive shell reads ~/.bashrc.

The result is that to get a sane behavior, you
1) put "every process" stuff in ~/.bashrc (as if it was your POSIX $ENV file)
2) put "just once" stuff in ~/.bash_profile, and then at the bottom of that
file
   put ". ~/.bashrc"
3) in order to work around that braindead 'read .bashrc under rsh, or maybe
ssh'
   behavior, put the following at the *very top* of your ~/.bashrc:
      case $- in *i*) ;; *) return;; esac
   That makes bash stop reading the .bashrc when non-interactive.

Of particular importance is that stuff that generates output or that
resets the terminal should *never* be processed by a non-interactive
shell.

Finally, you should change your X defaults so that xterm starts a
login shell, either by always passing it the -ls option, or by
slipping "XTerm*loginShell: true" into your X resources somewhere.
The details of how to do that are quite variable due to the twisty
maze of X resource processing (you are likely to be eaten by a grue).

(Some people suggest having your .xsession set the environment stuff
that your .profile does and then not start login shell in xterms, but
that increases the code duplication or involves splitting the files
into more parts.  Not Worth It, IMHO.)


> So i guess .bashrc is not the name
> the file should have anyway 'cos only root will read it in regular
> xterm sessions, not the regular user...

Uh, what?  What does being root have to do with this?  You aren't
logging into X as root, are you?!?!


Philip Guenther

Reply via email to