Bourne Again Shell

Lidt historie

Den oprindelige Unix-shell var skrevet af S. R. Bourne og havde et stærkt scriptingsprog, men ikke særlig god understøttelse for interaktiv brug.

Med csh kom job control og med tcsh kom komandolinjeredigering. Men csh og tcsh brugte et andet scriptingsprog og mange beholdte bourne shell til scripting.

David Korn fra AT&T lavede en shell med sproget fra bourne shell og de interaktive muligheder fra (t)csh. Men ksh var ikke frit distribuerbar.

POSIX standardiserede en bourne shell der på en række punkter lignede Korn shell.

GNU projektet havde behov for en fri POSIX-kompatibel shell. Dette blev Bourne Again Shell, bash


Features og disfeatures

En del af GNU projektet og under GNU General Public License

Standard-shell på linux-bokse.

Readline key bindings, normalt Emacs-like men kan sættes til VI-like.

Kraftig history-funktionalitet (*)

Aliasser og funktioner

Fuldt programmerbare completions

Process Substitution (*)

Parameter Expansion (noget kraftigere end SUSv3) (*)


Process Substitution

Det hænder tilpas ofte at jeg gør noget ala:

$ cd /some/path/ ; find ... | xargs grep -l ... > /tmp/foo.quux
$ cd /other/path/ ; find ... | xargs grep -l ... > /tmp/foo.xyzzy
$ diff /tmp/foo.quux /tmp/foo.xyzzy

Med 'Process substitution' kan dette gøres uden midlertidige filer:

$ diff <(cd /some/path; find ... | xargs grep -l ...) <(cd /other/path; find ... | xargs grep -l ...)

Ikke meget kortere, men jeg skal ikke holde styr på midlertidige filer. På lignende vis kan man lave komandoer der skrives til:
$ cmd1 -o >(cmd2)

Parameter Expansion

Vi kender alle sammen almindelig variabelsubsitiotion hvor ${foo} bliver erstattet af indholdet af variablen foo.

SUSv3 giver nogle flere muligheder, blandt andet en standardværdi:

$ foo=quux
$ echo ${foo}
quux
$ echo ${foo:-bar}
quux
$ unset foo
$ echo ${foo:-bar}
bar
$ 

og at fjerne største og mindste prefix eller suffix:

$ x=/usr/src/linux/init/main.c
$ echo ${x%/*}
/usr/src/linux/init
$ echo ${x##*/}
main.c
$ 

bash giver blandt andet mulighed for delstreng:

$ foo=foobarbaz
$ echo ${foo:3}
barbaz
$ echo ${foo:3:3}
bar
$ 

Og substitution

Eksemplet slettet af korrekturen!!!

Bemærk at der bruges globbing og ikke regexps


History

bash har en kraftig history-funktion. Basalt set kan man med !! få sidste kommando og med !-n få n kommandoer tilbage.

Derudover kan man bruge en række modifiers, mest interessant nok substitution:

$ ls *.png
bar.png  baz.png  foo.png
$ !!:s/png/jpg/
ls *.jpg
plugh.jpg  quux.jpg  xyzzy.jpg
$ 

Med modifieren p kan man få den til ikke at udføre kommandoen, men kun skrive den ud:

$ ls *.png
bar.png  baz.png  foo.png
$ !!:s/png/jpg/:p
ls *.jpg
$ 
Peter Makholm, peter@makholm.net