bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: why ~/.bashrc in ssh or scp??


From: Stephane Chazelas
Subject: Re: why ~/.bashrc in ssh or scp??
Date: Tue, 18 Jan 2005 09:01:49 +0000
User-agent: Mutt/1.5.6i

On Mon, Jan 17, 2005 at 03:01:54PM -0500, Chet Ramey wrote:
> Stephane Chazelas wrote:
> >I find bash policy about startup files a bit confusing. I've
> >never quite understood why login shells wouldn't read the
> >~/.bashrc file (I would have considered this file as in other
> >shells or even other programs as the customization file, so why
> >not applying customizations to the login shells?).
> 
> I don't want to speak for Brian, since this behavior was in bash
> before I got involved with it, but I have always assumed that it
> was a compromise between the traditional sh and csh behaviors.
> 
> You can make bash behave just like sh:  .profile and no .bashrc,
> or like csh:  .bash_profile which sources .bashrc and .bashrc.

With csh .cshrc is read by login shells.

~$ cat > ~/.cshrc
echo cshrc
~$ cat > ~/.login
echo login
~$ csh
cshrc
% exit
~$ csh -l
cshrc
login
%

Which makes sense. Same for zsh.

In bash, you need something like:

[ -n "${BASH_VERSION+set}" ] &&
  [ -f ~/.bashrc ] &&
  [ -r ~/.bashrc ] &&
  case $- in
    *i*) . ~/.bashrc;;
  esac

in ~/.bash_profile

> >I've just discovered that the shells run with -c 'command line'
> >within a ssh or rsh non-interactive session were reading the
> >~/.bashrc. This left me very perplex.
> >
> >Someone suggested that it might be so that:
> >
> >in
> >
> >local-shell$ ssh some-host
> >remote-shell$ some shell command line
> >remote-shell$ exit
> >local-shell$
> >
> >and in
> >
> >ssh some-host 'some shell command line'
> >
> >The "some shell command line" is interpreted the same way.
> 
> Pretty much.  It's a way for people to use the same $PATH on the
> remote host they get when starting an interactive shell session.

PATH is a session setting, and is an environment variable. So,
it's typically something you put in ~/.profile (the login
session configuration file), not the ~/.shellrc (the interactive
shell customization file).

It looks like you want that shell run by rshd/sshd to behave as
a login shell (set the users login session settings), or said
otherwise, have sshd start a login session (without the utmp
stuff however). Non login shells are supposed to be run within a
login session, that's why they don't read ~/.profile again, only
~/.bashrc for non-persistent customizations (aliases, functions
as opposed to env vars, stty...). So considering the sshd bash
-c non-interactive shells the same way as interactive shells run
within a login session looks a bit bogus to me.

> It was originally intended for use with rsh, and extended to
> ssh (through several iterations) when folks complained that ssh's
> .environment file wasn't up to the job.
> 
> >And shouldn't it be limited to the bash instances run by sshd or
> >rshd and not every bash instance started during the session?
> 
> Sure, in a perfect world.  Unfortunately, the heuristics used to
> decide whether or not a command is run by rshd (-c command,
> stdin is a socket, $SHLVL < 2) can be fooled.

Yes. 

> >Also, why should the behavior be different in "rsh" and in "rsh
> >-n"?
> 
> Because one of the heuristics is that stdin be a socket.  With
> `rsh -n', stdin is closed.

Yes, but you'd agree that from a functionnal point of view, that
doesn't make much sense. So that "feature" is a bit bogus, it
may have more drawbacks that advantages.

To my mind, if you don't want to modify the start-up file
policy, you should at least give some advices on how to write
them in the documentations.

Like:

- The bash run just upon your logging in doesn't source the
  customization file (~/.bashrc) by default. But, as it sources
  the session file, you can put a call to ". ~/.bashrc" there if
  you want your customizations to also apply to login shells..
  If you use a shell independant profile file (~/.profile)
  however, you have to check wether the shell is bash or use
  ~/.bash_profile instead.
  .
  As login shells are not necessarily interactive (as the ones
  started by some desktop environments), you also have to check
  the shell is not interactive. A typical code for it would be:

  [ -n "${BASH_VERSION+set}" ] &&
    [ -f ~/.bashrc ] &&
    [ -r ~/.bashrc ] &&
    case $- in
      *i*) . ~/.bashrc;;
    esac

- it should be noted that for convenience, in some cases the
  ~/.bashrc is sourced by non-interactive shells (for instance,
  the shell that interprets a remote-sh or secure-sh command
  line). So, when writing your ~/.bashrc, you have to pay
  attention to that. In particular, if you have some application
  that relies on ssh or rsh for its internal use, you should
  make sure that no function definition or option setting won't
  affect its behavior. If some customizations only make sense
  for interactive shells (for instance, terminal settings), you
  should wrap them in:

  if [[ -o interactive ]]; then
    # customizations here
  fi


-- 
Stéphane





reply via email to

[Prev in Thread] Current Thread [Next in Thread]