Using non base shells

From FBSD_tips

Jump to: navigation, search

D'OH! I locked my keys in my car or how to safely get the shell you want.

OR

nothing teaches fire is hot like burned fingers

Contents

[edit] Rationale

At some point you may be tempted to chsh(1) your shell to something exotic, or just something you have gotten used to, maybe from another platform. This is a bad habit and I will explain why, using bash as the example, although the principal is the same for any non base shell.

[edit] Background

Bash has several dependancies in it's default configuration in ports. :

 pkg_info -rX bash
Information for bash-3.1.17:

Depends on:
Dependency: libiconv-1.9.2_2
Dependency: gettext-0.14.5_2

If either of these dependancies get corrupted or even upgraded significantly the installed bash may become non-functional. If you have made your login shell bash, this is what you would see.

[edit] Demonstration

[edit] Locked out

# ssh test@10.10.10.10
Password: 
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
        The Regents of the University of California.  All rights reserved.

FreeBSD 6.2-RELEASE (SMP) #0: Fri Jan 12 11:05:30 UTC 2007
 
Welcome to FreeBSD!

Before seeking technical support, please use the following resources:

o  Security advisories and updated errata information for all releases are
   at http://www.FreeBSD.org/releases/ - always consult the ERRATA section
   for your release first as it's updated frequently.

o  The Handbook and FAQ documents are at http://www.FreeBSD.org/ and,
   along with the mailing lists, can be searched by going to
   http://www.FreeBSD.org/search/.  If the doc distribution has
   been installed, they're also available formatted in /usr/share/doc.

If you still have a question or problem, please take the output of
`uname -a', along with any relevant error messages, and email it
as a question to the questions@FreeBSD.org mailing list.  If you are
unfamiliar with FreeBSD's directory layout, please refer to the hier(7)
manual page.  If you are not familiar with manual pages, type `man man'.

You may also use sysinstall(8) to re-enter the installation and
configuration utility.  Edit /etc/motd to change this login announcement.

/libexec/ld-elf.so.1: Shared object "libintl.so.6" not found, required by "-bash"
Connection to 74.95.184.164 closed.

[edit] Not locked out

I picked gettext because I have seen this particular package change 'out from under' ports before, and it seems that quite a number depend on it. So ... how can we have our cake and eat it too? Simple. Put 'bash -l' in your shell's startup file. In the case of /bin/sh it will go into .shrc. it's effect on the 'damaged' machine will be the following :

$ ssh test@74.95.184.164
Password:
Last login: Thu Oct 18 12:21:11 2007 from 74.95.184.161
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
        The Regents of the University of California.  All rights reserved.

FreeBSD 6.2-RELEASE (SMP) #0: Fri Jan 12 11:05:30 UTC 2007

Welcome to FreeBSD!

Before seeking technical support, please use the following resources:

o  Security advisories and updated errata information for all releases are
   at http://www.FreeBSD.org/releases/ - always consult the ERRATA section
   for your release first as it's updated frequently.

o  The Handbook and FAQ documents are at http://www.FreeBSD.org/ and,
   along with the mailing lists, can be searched by going to
   http://www.FreeBSD.org/search/.  If the doc distribution has
   been installed, they're also available formatted in /usr/share/doc.

If you still have a question or problem, please take the output of
`uname -a', along with any relevant error messages, and email it
as a question to the questions@FreeBSD.org mailing list.  If you are
unfamiliar with FreeBSD's directory layout, please refer to the hier(7) 
manual page.  If you are not familiar with manual pages, type `man man'.

You may also use sysinstall(8) to re-enter the installation and
configuration utility.  Edit /etc/motd to change this login announcement.

/libexec/ld-elf.so.1: Shared object "libintl.so.6" not found, required by "bash"
$

So, as tou can see by the '$' prompt, now we are not locked out and can fix the issue.

[edit] Fixing

$ su -l
Password:
/libexec/ld-elf.so.1: Shared object "libintl.so.6" not found, required by "bash"
test# pkg_add -r gettext
Fetching ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-6.2-release/Latest/gettext.tbz... Done.
test#

You notice the same message whenI su to root as well, this is because I also have root's startup, .cshrc with 'bash -l' inside the "if ($?prompt)" block.

test# test# cat .cshrc
# $FreeBSD: src/etc/root/dot.cshrc,v 1.29 2004/04/01 19:28:00 krion Exp $
#
# .cshrc - csh resource script, read at beginning of execution by each shell
#
# see also csh(1), environ(7).
#

alias h         history 25
alias j         jobs -l
alias la        ls -a
alias lf        ls -FA
alias ll        ls -lA

# A righteous umask
umask 22

set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin /usr/X11R6/bin $HOME/bin)

setenv  EDITOR  vi
setenv  PAGER   more
setenv  BLOCKSIZE       K

if ($?prompt) then
        # An interactive shell -- set some stuff up
        set prompt = "`/bin/hostname -s`# "
        set filec
        set history = 100
        set savehist = 100
        set mail = (/var/mail/$USER)
        if ( $?tcsh ) then
                bindkey "^W" backward-delete-word
                bindkey -k up history-search-backward
                bindkey -k down history-search-forward
        endif
        /usr/local/bin/bash -l 
endif

The exec of bash is done inside the 'if prompt' block to ensure that this is only done when invoked as an interactive shell. There can be weird side effects if this is not done this way

A side effect of this startup is that you will have to exit from 2 shells instead of just one. A test for an exit code of '0' can make this go away. I leave it like this because it is POSSIBLE (although very unlikely) that a failure case could still exit with a code of '0'. Here is the code snippet to implement this check :

/usr/local/bin/bash -l
if($status == 0) then
 logout
endif

[edit] Discussion

One obvious artifact of this is the fact that you will have to exit twice, first from the 3rd party shell and then from the base default shell. This could likely be fixed by checking the exit code, but i am not positive that all types of possible damage bash could suffer would make a non-zero exit code.

Another is that $SHELL is still be set to /bin/csh. You could fix this by making a ~/.bashrc that set it.

A discussion of the toor account in the official security FAQ :http://www.freebsd.org/doc/en_US.ISO8859-1/books/faq/security.html#TOOR-ACCOUNT

The handbook on Shells : http://www.freebsd.org/doc/en_US.ISO8859-1/articles/linux-users/article.html#SHELLS

Gongo 19:11, 19 October 2007 (UTC)


I went ahead and set the .profile to exit if the exit status of bash was non-zero, and it's saved me once already. I checked with some bash people, who informed me that more likely than getting bash to exit with zero when it shouldn't would be bash exiting non-zero when everything was fine. I also set the $SHELL in my .bashrc, and everything is working well. --Mersault 00:29, 10 April 2008 (UTC)

Personal tools