Opened 11 years ago

Closed 10 years ago

Last modified 10 years ago

#40603 closed defect (fixed)

MacPorts bash doesn't work properly as a default shell (should define SH_SOURCE_BASHRC)

Reported by: dlitz@… Owned by: raimue (Rainer Müller)
Priority: Normal Milestone:
Component: ports Version: 2.2.0
Keywords: Cc:
Port: bash

Description

The bash port shipped with MacPorts doesn't work properly when a user sets it up as their default shell.

Steps to reproduce

  1. port install bash
  2. Add /opt/local/bin/bash to /etc/shells
  3. Make sure OSX's bash is your default shell:
    chsh -s/bin/bash
    
  4. Put something like this at the top of your ~/.bashrc:
    echo "Hello from $BASH"
    
  5. Run "ssh localhost true". You should see "Hello from /bin/bash".
  6. As a user, change your shell to MacPorts bash:
    chsh -s/opt/local/bin/bash
    
  7. Run "ssh localhost true" again.

What you should see

$ chsh -s/bin/bash
Changing shell for dlitz.
Password for dlitz:
$ ssh localhost true
Hello from /bin/bash
$ chsh -s/opt/local/bin/bash
Changing shell for dlitz.
Password for dlitz:
$ ssh localhost true
Hello from /opt/local/bin/bash
$

What you actually see

$ chsh -s/bin/bash
Changing shell for dlitz.
Password for dlitz:
$ ssh localhost true
Hello from /bin/bash
$ chsh -s/opt/local/bin/bash
Changing shell for dlitz.
Password for dlitz:
$ ssh localhost true
$

Explanation

There's an option in config-top.h that's not enabled by default, but it's usually defined by Linux distros, and by Apple in OSX:

/* Define this if you want bash to try to check whether it's being run by
   sshd and source the .bashrc if so (like the rshd behavior).  This checks
   for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment,
   which can be fooled under certain not-uncommon circumstances. */
/* #define SSH_SOURCE_BASHRC */

This needs to be enabled.

Impact

This breaks things like git or hg over ssh.

Solution

Add the following to bash's Portfile:

configure.cflags-append "-DSSH_SOURCE_BASHRC"

Change History (6)

comment:1 Changed 11 years ago by ryandesign (Ryan Carsten Schmidt)

Owner: changed from macports-tickets@… to raimue@…

comment:2 Changed 11 years ago by raimue (Rainer Müller)

Status: newassigned

Thank you for the very detailed report and the steps to reproduce the issue. You are indeed correct that the version of bash distributed by Apple has SSH_SOURCE_BASHRC enabled. There seem to be some twists with enabling this. The bash upstream maintainer actually advises against it (that's why it isn't enabled by default). I am in the process of checking which other distributions enable this as well, but it seems like almost every Linux distribution does it.

The usual workaround for the different startup files for interactive and login shells would be to to source .bashrc from your .bash_profile. That is what I am using and thus never noticed a problem. However, if you do this, make sure you do not make any output on stdout as it would break non-interactive protocol connections over SSH (e.g. scp or rsync).

# Source .bashrc if it exists
if [ -r ~/.bashrc ]; then
    source ~/.bashrc
fi

comment:3 Changed 10 years ago by dlitz@…

Thanks, but one clarification:

The usual workaround for the different startup files for interactive and login shells would be to to source .bashrc from your .bash_profile.

That's about login vs non-login shells, and SSH_SOURCE_BASHRC doesn't change that behavior. This is about running .bashrc from a non-interactive shell, such as when you try to use git pull over SSH from a repository on your Mac.

The bash upstream maintainer actually advises against it (that's why it isn't enabled by default). I am in the process of checking which other distributions enable this as well, but it seems like almost every Linux distribution does it.

I assume you're referring to this comment by Chet Ramey(1):

Here's the problem: consider a user who runs a shell that doesn't understand $SHLVL in the same way bash does (they do exist). They ssh to a system with bash modified with SSH_SOURCE_BASHRC enabled. Every time they run, explicitly (unlikely) or via some other agent (more likely), `bash -c command', their .bashrc file, if it exists, will be read, as will the system /etc/bashrc if that's been enabled. This will lead to some really obscure bug reports. It's happened.

Chet's criticism is valid. Adding special-case knowledge of SSH into the shell is a dirty hack, and it would be better if everyone could agree on some way of allowing the user to set environment variables dynamically prior to loading the shell (e.g. in a PAM module or something). However, that has its own problems, e.g. for "restricted shells". Right now, it seems that there's no easy, clean solution and it doesn't seem to be on anybody's agenda to actually solve this problem any time soon (especially in a cross-platform way).

Right now, setting environment variables on OSX outside ~/.bashrc is a pretty big mess(2). SSH_SOURCE_BASHRC is quite clean, in comparison, and much more flexible.

There's a reasonable argument that SSH_SOURCE_BASHRC is the wrong approach to this problem in general. However, the fix is something that can only be properly solved by the OS vendor. The issue that Chet points out isn't solved by having MacPorts bash behave differently from Apple bash: Programs on OSX need to cope with the behavior of Apple bash anyway.

So, despite the (valid) criticism of this approach in general, it would still be better if MacPorts bash behaved the same Apple bash here, regardless of what other distros do.

At the moment, using MacPorts bash as my login shell breaks git pull my-mac:~/path/to/repo.

(1) http://lists.gnu.org/archive/html/bug-bash/2007-12/msg00028.html

(2) http://stackoverflow.com/questions/603785/environment-variables-in-mac-os-x/4567308#4567308

Last edited 10 years ago by dlitz@… (previous) (diff)

comment:4 in reply to:  3 Changed 10 years ago by raimue (Rainer Müller)

Replying to dlitz@…:

Right now, setting environment variables on OSX outside ~/.bashrc is a pretty big mess(2). SSH_SOURCE_BASHRC is quite clean, in comparison, and much more flexible.

I agree. The different environments often pose a problem.

There's a reasonable argument that SSH_SOURCE_BASHRC is the wrong approach to this problem in general. However, the fix is something that can only be properly solved by the OS vendor. The issue that Chet points out isn't solved by having MacPorts bash behave differently from Apple bash: Programs on OSX need to cope with the behavior of Apple bash anyway.

So, despite the (valid) criticism of this approach in general, it would still be better if MacPorts bash behaved the same Apple bash here, regardless of what other distros do.

Yes, of course the compatibility with Apple's bash is important (although it's quite old now). I meant I checked whether there are effects on other tools we should be aware of. But so far, I did not experience any problem, so I enabled this now in bash @4.2.45_2.

Committed in r112140.

comment:5 Changed 10 years ago by raimue (Rainer Müller)

Resolution: fixed
Status: assignedclosed

comment:6 Changed 10 years ago by dlitz@…

I just tried it and it works great. Thanks!

Note: See TracTickets for help on using tickets.