TITLE: How to install alternative shells on your LFS-system LFS VERSION: All AUTHOR: Björn Lindberg SYNOPSIS: A guide on how to install other shells than bash on an LFS-system. HINT: 1. INTRODUCTION A vanilla LFS only comes with one shell, namely bash (Bourne-again shell). There are a lot of reasons why one would like to have alternatives. Different shells are good at different things. You might want to use one particular shell as your interactive shell, but another one for scripting. There are some programs that have their compile scripts written with a syntax that requires a certain shells. I will give a brief description of each shell, listing some of their strong points below. 1.1 The Almquist Shell (ash) This is the shell that most closely tries to mimick the behaviour of the original Bourne shell -- and no more. It is therefore Bourne shell compliant, while being extraordinarily small and efficient. It is used as the /bin/sh shell on NetBSD, who also currently maintains it. There are two good reasons why you might want to consider installing ash: (1) It is small. It's memory footprint is about a third of bigger more feature-filled shells, like bash and Korn shell. On a less powerful machine it could be installed as /bin/sh, causing all common administration scripts, eg. boot scripts to be run with it. (2) Portability. On Linux systems it is commonplace to begin a script with /bin/sh, yet oftentimes bash-specific features will creep in, since bash is the Linux standard shell. Those scripts should arguably have /bin/bash at the top, because most of them won't run as intended on other flavors of UNIX that don't use bash for their /bin/sh, like the *BSDs and commercial Unices. Thus, using ash for /bin/sh is an extra insurance that your scripts are portable in the sense that they will generally work with the interpreter given on the first line. this is good. 1.2 The Korn Shell (ksh) Korn shell, like bash, is an improved Bourne shell derivative. It is actually more than a shell, designed to be a very high-level programming language while still maintaining Bourne shell compatibility. Bash has borrowed a lot of the ksh functionality, so the syntax is very similar. Korn shell is commonly used for more advanced scripting on non-Linux platforms, and since ksh is frequently available on commerical Unices, the portability for ksh scripts is good. It is also a very good interactive shell, and has some distinct features, like co-processes. See http://www.kornshell.com for more info. 1.3 The T C Shell (tcsh) T C shell is the successor of the C shell, a competitor to the Bourne shell but with C-like syntax. tcsh thus has a vastly different syntax than the Bourne shell derivatives. Although shell afficionados consider csh (and by extension tcsh) a bad scripting shell (see http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/), it is a very nice interactive shell with some unique features, like programmable tab completion. Another good reason to have it is that you might encounter scripts written in csh or tcsh. Such scripts won't run with Bourne shell and compatibles, since the syntax is different. Some program sources requires tcsh to build, eq xv (the image viewer), and openoffice. See http://www.tcsh.org for more info on tcsh. 1.4 The Z shell (zsh) The Z shell is the most feature-filled (or bloated :-) of our shells. It's syntax is mostly similar to the Korn shell, but also borrowing elements from the C shell. It strongpoints are as an interactive shell, where it incorporates features from all other shells, while containing modules with a large variation of functionality. As an example, zsh comes with it's built-in ftp-client! See http://www.zsh.org for more info. 2. INSTALLATION 2.1 The Almquist Shell As mentioned earlier, the most actively maintained ash is the one NetBSD are using for their /bin/sh. Most Linux-distros are including ash, and they are then typically keeping their sources in sync with the NetBSD ones. We will use the Debian sources, since they are a bit more Linux-friendly than NetBSD. :-) It is still a lot of trouble to compile though, because the makefile requires pmake, which is a make common on *BSDs. Gnu make won't work. The tarballs we'll need, and the places I got them: ash ftp://ftp.debian.org/debian/dists/potato/main/source/shells/\ ash_0.3.5.orig.tar.gz ash-diff ftp://ftp.debian.org/debian/dists/potato/main/source/shells/\ ash_0.3.5-11.diff.gz ash-hetios ftp://ftp.psychosis.com/linux/linux-router-devel/\ ash-hetios-0.5.1.diff.gz pmake ftp://ftp.debian.org/debian/dists/potato/main/source/devel/ \ pmake_1.45-3.2.tar.gz We might as well use the Debian pmake, found at the same place. Don't hesitate to use your local Debian mirror site instead of the main one. The ash-hetios patch is a patch from the Linux Router Project that enables history support and arrow keys. If you plan on using ash as an interactive shell, you would want this patch, and if not, just don't apply it. In the section below I will assume that you do not want to keep pmake after using it to build ash. If you want to install pmake on your system the procedure will actually be somewhat easier. Unpack the pmake tarball and issue the following command: debian/rules We will need this later: export PMAKE= export PATH=$PATH:$PMAKE If you want to install pmake on your system, instead do the following: install -m 755 bmake /usr/bin/pmake install -m 755 mkdep /usr/bin/ install -m 644 make.1 /usr/share/man/man1/pmake.1 install -m 644 mkdep.1 /usr/share/man/man1/ install -d -m 755 /usr/share/mk/ for file in mk/*; do install -m 644 $file /usr/share/; done Now unpack the ash tarball and apply first the debian diff, and then the hetios diff. The hetios diff will not apply cleanly beacuse it was made against a slightly different source tree. This is nothing to worry about. We still have to make some small modifications: mv Makefile Makefile.orig sed 's/\(^CPPFLAGS.*$\)/\1 -DHETIO/' Makefile.orig > Makefile echo -e "#endif\n" >> hetio.c mv arith.y arith.y.orig sed 's/\(yyerrok;\)/\/* \1 *\//' arith.y.orig > arith.y $PMAKE/pmake -m $PMAKE/mk CFLAGS='-O2' CPPFLAGS='-DBSD \ -DSMALL -DSHELL -DHETIO -D__COPYRIGHT\(x\)= \ -D__RCSID\(x\)=' HOST_CPPFLAGS='-DBSD -DSMALL \ -DSHELL -DHETIO -D__COPYRIGHT\(x\)= \ -D__RCSID\(x\)=' YACC='bison -y' Voilà! We now have a binary called sh and a manpage to go with it. Install via the following: install -m 755 sh /bin/ash install -m 644 sh.1 /usr/share/man/man1/ cd /usr/share/man/man1 && ln sh.1 ash.1 If you would like to use ash as /bin/sh, either symlink it or install it as sh directly. The manpage is a very good manpage for sh in either case. 2.2 The Korn Shell The Korn SHell used to be a commercial closed-source shell. Because of this, a free clone was written, pdksh (Public Domain Korn Shell). pdksh supposedly has most of the original ksh's functionality, but since early 2000 the source code for the original ksh is available, so that is what we are going to install here. Note that ksh is still under a license though. The following packages are needed: http://www.research.att.com/~gsf/download/tgz/INIT.2002-06-28.tgz http://www.research.att.com/~gsf/download/tgz/ast-ksh.2002-06-28.tgz http://www.research.att.com/~gsf/download/tgz/ast-ksh-locale.2002-06-28.tgz Note that the exact URL may change as a result of updates to the source code packages. If the above links don't work you will have to go to http://www.research.att.com/sw/download/ and manually download the following packages: INIT, ast-ksh and ast-ksh-locale. ksh is built using AT&T's particular build system. First you will need to designate an empty build directory, eg <...>/src/ksh. The rest of the install commands should be executed while standing in this directory. Unpack the INIT package from this directory. Execute mkdir lib/package/tgz and move all three packages to this directory. Now issue bin/package read bin/package make To install ksh cp arch/linux.i386/bin/ksh /bin cp arch/linux.i386/man/man1/sh.1 /usr/share/man/man1/ksh.1 To install the provided shell functions pushd, popd and dirs, do this mkdir -p /usr/share/ksh/functions cp arch/linux.i386/fun/* /usr/share/ksh/functions you will then have to set the following environment variable to access them, this can be done in one of the startup scripts export FPATH=/usr/share/ksh/functions The install management system supposedly will make it easier to upgrade ksh to a newer version by the following command bin/package update source http://www.research.att.com/sw/download 2.3 The T C Shell tcsh is by comparison easy to install. First we need the sources: ftp://ftp.funet.fi/pub/unix/shells/tcsh/tcsh-6.11.tar.gz Build the sources ./configure --prefix=/usr --bindir=/bin --mandir=/usr/share/man mv config_f.h config_f.h.orig sed '/NLS_CATALOGS/s/undef/define/; /AUTOLOGOUT/s/define/undef/' \ config_f.h.orig > config_f.h make make install install.man That's it! You now have a shiny new tcsh in your /bin directory. If you have special considerations you might want to edit the settings in config_f.h differently from mine, for instance it is possible to set vi editing as default. If you want to play with the programmable tab completion feature, have a look at the file complete.tcsh. 2.4 The Z Shell The sources are available for instance here: ftp://sunsite.dk/pub/unix/shells/zsh/zsh-4.0.4.tar.bz2 Building and installation is straightforward ./configure --prefix=/usr --bindir=/bin --mandir=/usr/share/man make make install This will install, in addition to the shell, the shell modules as well as a lot of shell functions. To take advantage of the latter, you need to set the following environment variable, and also "autoload" the functions you would like to use fpath=(/usr/share/zsh/4.0.4/functions/) autoload zed # example 3. Startup files To learn more about the different shells, I recommend the manpages and homepages for the shells, as well as the general web resources listed in section 5. I will however say something about startup files, which is otherwise often a source of confusion. Beginning with ash and ksh, all shells (interactive, non-interactive and login) will read the file specified in $ENV. A login shell will in addition to this first read /etc/profile and .profile. It is common to set $ENV from one of those two files with a command such as this ENV=$HOME/.shrc; export ENV # or export ENV=$HOME/.kshrc To restrict parts of the $ENV file to interactive shells (that will not be run for eg shell scripts), something like the following can be used case $- in *i*) # interactive commands # ... esac A tsch login shell will read the following files /etc/csh.cshrc /etc/csh.login ~/.tcshrc, or if not found, ~/.chsrc ~/.login a non-login shell will only read /etc/csh.cshrc and ~/.tcshrc (or ~/.cshrc). On logout, a login shell will read /etc/csh.logout and ~/.logout. A zsh login shell reads the following files /etc/zshenv ~/.zshenv /etc/zprofile ~/.zprofile /etc/zshrc ~/.zshrc /etc/zlogin ~/.zlogin an interactive (but non-login) shell will read all those but the *profile and *login files. A non-interactive shell will not read *zshrc. In addition, zsh login shells will also read ~/.zlogout and /etc/zlogout on exit. 4. Size comparisons Shell In-memory size (kB) Binary size (kB) ------------------------------------------- ash 472 97 bash 1400 533 ksh 1212 834 tcsh 1448 292 zsh 1472 424 All binaries were stripped. The in-memory size is obtained from the RSS column from 'top'. Sizes may vary slightly from system to system and also depending on exact shell version. I am actually not certain how relevant these figures are, but decided to include them for comparison. Another thing to keep in mind is that zsh uses a lot of modules that also takes up space, so the total disk space needed are higher than the above figure. The total zsh installation uses over 3 MB. 5. Shell resources http://www.shelldorado.com http://www.faqs.org/faqs/unix-faq/shell/shell-differences/ http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/ http://www.kornshell.com http://www.tcsh.org http://www.zsh.org