Praktische Unterschiede von Bash 5.0 zu Bash 4.4

Bas_20191118-153114_1

Seit Januar 2019 ist Bash 5.0 allgemein verfügbar. Dieses aktuelle Major-Release ist ca. 10 Jahre nach dem Major-Release 4 erschienen. In diesem Artikel sollen einige praktische Unterschiede zur vorherigen Version Bash 4.4 aus dem Jahr 2016 dargestellt werden.  

Historie 

Bei der Bash (Bourne-again Shell) handelt es sich um einen Kommandozeileninterpreter. Die Entwicklung begann 1987 (Brian Fox) für das GNU-Projekt und wurde 1990 von Chet Ramey weitergeführt. Aktuellste Version ist die Version 5.0.  

Bash 5.0

In der Hauptsache wurden Bugfixes zur Version 4.4 durchgeführt. Es gibt jedoch auch einige Neuerungen. Die interessantesten werden in diesem Artikel vorgestellt.  

Variablen

Es gibt drei neue Umgebungsvariablen:

EPOCHSECONDS:

Anzahl der Sekunden seit der UNIX-Epoche (1.1.1970, Mitternacht UTC/GMT) ; (entspricht „date +%s")

EPOCHREALTIME:
dto. , aber mit zusätzlicher Ausgabe von Mikrosekunden; (entspricht „date +%s.%6N")

BASH_ARGV0:
Name der Shell oder eines ausgeführten Shell-Skripts (Interaktion mit $0)

Beim Ändern der Variablen BASH_ARGV0 wird auch die Variable $0 mit verändert. Grund hierfür ist: beim Debuggen kann es nützlich sein, $0 auf verschiedene Werte zu setzen. Dies führte vor zehn Jahren zum Vorschlag vom BASH Debugger Rocky Bernstein dazu, es in die BASH einzubauen.

Man könnte sich fragen, warum eine neue Variable benötigt wird, anstatt es $0 direkt zuzuweisen. Da 0 jedoch kein gültiger Variablenname ist, wäre es weit aufwändiger es dort einzubauen und auch inkompatibel mit den Vorgängerversionen! Die Variable $0 erlaubt ja nur ihren Wert zu lesen. Vor der BASH 5 konnte es nur beim Starten der Shell gesetzt werden. Mit BASH_ARGV0 kann man den Wert nun sowohl lesen als auch schreiben.

Beispiele: 

$ echo $EPOCHSECONDS;  date +%s;  date -d @$EPOCHSECONDS
1571910528
1571910528 
Do 24. Okt 11:48:48 CEST 2019
 
$ echo $EPOCHREALTIME;  date +%s,%6N
1571910528,646358
1571910528,648351
 

Ändern der $0-Variablen:

$ echo $0
bash
$ BASH_ARGV0="Ich bin keine BASH :-)“
$ echo $0
Ich bin keine BASH :-)
 

Shell Builtin Kommandos 

Bei einen Builtin Kommando der Shell handelt es sich um ein Kommando, welches in der Shell eingebaut ist. Diese Kommandos werden im RAM geladen und sind dadurch vom Zugriff schneller im Vergleich zu externen Kommandos, die von der Platte geladen werden müssen. Builtin Kommandos können auch dynamisch geladen werden. 

Syntax:


Anzeige, ob Builtin Kommandos enabled/disabled sind

Disabled ein geladenes Builtin Kommando

Enabled ein geladenes Builtin Kommando

Lädt dynamisch ein Builtin Kommando

Entfernt ein dynamisch geladenes Builtin Kommando

Syntax:

enable -a 

enable -n name 

enable name

enable -f datei name 

enable -d name

Die Anzahl der Builtin Kommandos hat sich leicht erhöht (s.u.) und es wurden auch Änderungen an einigen vorhandenen Builtin Kommandos eingebaut:

Shell builtin Kommando history:
Mit diesem Kommando kann man sich die letzten ausgeführten Kommandos (max. $HISTSIZE) anzeigen lassen und auch die History-Liste bearbeiten.

Neu in der BASH 5 ist, dass man nun auch Bereiche entfernen kann, nicht nur wie vorher einzelne Elemente:

Syntax:

history -d START-END

Beim Löschen von einzelnen Elementen lassen sich nun aber auch negative Offsets verwenden.

Beispiele: 

Löschen der Einträge 100 bis 200

Löschen der letzten 10 Einträge (genauer von -10 bis -1)

Löschen des 3. letzten Kommandos

$ history -d 100-200 

$ history -d -10–-1

$ history -d -3

Shell builtin Kommando wait

Neue Option -f bedingt, dass gewartet wird bis der Job oder der Prozess terminiert und nicht nur bis der Status sich ändert.

Shell Builtin Kommando umask

umask akzeptiert nun auch 4-stellige oktal-Werte - was bei vielen anderen Shells ( ksh, dash, sh, zsh, … ) schon längere Zeit möglich war - wobei aber nur 3 Stellen interpretiert werden:  

Beispiel: 

$ umask 7777
$ umask
0777 

Shell Builtin Kommando times

Dieses Kommando zeigt den Zeitverbrauch an. Es gibt den akkumulierten Benutzer- und Sysemzeitverbrauch der Shell und aller von ihr gestarteten Prozesse aus. Es berücksichtigt jetzt die auch Sprachumgebung, genauer locale​, so dass Dezimalzahlen je nach Sprachumgebung mit Punkt oder Komma dargestellt werden, so wie es das Laufzeit-Mess-Kommando „time" schon länger macht.

Beispiel

$ echo $LANG
de_DE.UTF-8
$ times
0m0,033s 0m0,049s
0m0,333s 0m0,085s

$ LANG=C times
0m0.033s 0m0.049s
0m0.333s 0m0.085s 

Es gibt vier neue "loadable" Builtin Kommandos:

rm;      stat;      fdflags;      seq

Diese können aktuell nur eingesetzt werden, wenn man den Quellcode der BASH 5 installiert hat. Dazu müssen sie zuerst per make generiert werden:

# cd /opt/bash-bash-5.0/examples/loadables
# make rm
# make stat
# make fdflags
# make seq 

Das Builtin Kommando rm arbeitet recht analog zum gleichnamigen Unix Kommando, kennt aber nicht die gleichen Argumente (es fehlen -I -d und -v ).

So werden die generierten Shell-Builtins aktiviert, bzw. deaktiviert:

Beispiel: 

# type rm
rm is /usr/bin/rm
# enable -f /opt/bash-bash-5.0/examples/loadables/rm rm
# type rm
rm is a shell builtin
# enable -d rm
# type rm
rm is /usr/bin/rm 

Das Builtin Kommando stat arbeitet auch analog zum gleichnamigen Unix Kommando, besitzt aber auch nicht die gleichen Optionen. Es schreibt sogar per default die Ausgabe in ein Array dessen Namen man mit der Option -A definieren kann, ansonsten wird der Array-Name STAT verwendet.  

  Beispiel:

# type stat
stat is /usr/bin/stat
# enable -f /opt/bash-bash-5.0/examples/loadables/stat stat
# type stat
stat is a shell builtin

# stat /etc/shells                                           
# for i in ${!STAT[*]}; do echo -e "$i\t : ${STAT[$i]}"; done
nlink	 : 1
link	 : /etc/shells
perms	 : 0644
inode	 : 8401182
blksize	 : 4096
device	 : 64768
atime	 : 1572962369
type	 : -
blocks	 : 8
uid	 : 0
size	 : 90
rdev	 : 0
name	 : /etc/shells
mtime	 : 1569869620
ctime	 : 1569869620
gid	 : 0


###  Mit der Option -l ist die Ausgabe länger und das Ergebnis besser lesbar:
# stat -l /etc/shells                                        

# for i in ${!STAT[*]}; do echo -e "$i\t : ${STAT[$i]}"; done
nlink	 : 1
link	 : /etc/shells
perms	 : u=rw,g=r,o=r
inode	 : 8401182
blksize	 : 4096
device	 : 64768
atime	 : Tue Nov  5 08:59:29 2019
type	 : -
blocks	 : 8
uid	 : 0
size	 : 90
rdev	 : 0
name	 : /etc/shells
mtime	 : Mon Sep 30 14:53:40 2019
ctime	 : Mon Sep 30 14:53:40 2019
gid	 : 0
 

Das Builtin Kommando fdflags zeigt an, bzw. ändert Filedeskriptoren eines Ein-/Ausgabekanals.

Das Kommando seq dient dazu Zahlen schrittweise auszugeben. Das Builtin Kommando ist aber nicht so einsatzfähig wie das binäre Kommando:

  Beispiel:

$ type seq                                       
seq is a shell builtin

$ seq  100000  3  100009                            
100000
100003
100006
100009

$ seq  10000000000000000000  3  10000000000000000009
-9223372036854775808

$ enable -d seq; type seq 
seq is hashed (/usr/bin/seq)

# seq  10000000000000000000  3  10000000000000000009
10000000000000000000
10000000000000000003
10000000000000000006
10000000000000000009
 

Readline Variable

  Wird die Variable completion-ignore-case gesetzt (die schon in der BASH 2 eingeführt wurde) , werden nun auch Shell-Funktionen und Aliase case-insensitv per TAB-Taste erkannt; bisher nur Datei- und Verzeichnisnamen

shopt Optionen (Auswahl)

Bei shopt handelt es sich um ein Builtin Kommando mit dem das Verhalten der Shell geändert werden kann. 

  Syntax:

$ shopt

  • Ohne Option werden alle shopt Optionen angezeigt.
  • Mit der Option -s können Optionen auf on (enabled) gesetzt werden.
  • Mit der Option -u können Optionen auf off (disabled) gesetzt werden.

Neue bzw. geänderte shopt Optionen:

Neu sind bei Bash 5.0 die folgenden 5 Optionen, so dass nun insgesamt 53 zur Verfügung stehen:

assoc_expand_once off

compat44 off

localvar_inherit off

localvar_unset off

progcomp_alias off


Geändert wurde bei der Bash 5.0 eine Standardeinstellung, die vorher deaktiviert war:

globasciiranges on

Damit werden Bereiche in Klammerausdrücken [..] wie bei C locale ausgewertet.

  Beispiel:

$ shopt  globasciiranges
globasciiranges on
$ echo $LANG
de_DE.UTF-8
$ ls [a-z]
a  b  c  d
$ ls [A-Z]
A  B  C  D 

Falls off: Bereiche werden entsprechend der "local collecting sequence" ausgewertet, (d.h. Variable $LANG, genauer locale wird ausgewertet)

Beispiel:

$ shopt  -u globasciiranges
$ echo $LANG
de_DE.UTF-8
$ ls [a-z]
a  A  b  B  c  C  d  D
$ ls [A-Z]
A  b  B  c  C  d  D

$ LANG=C
$ ls [a-z]
a  b  c  d
$ ls [A-Z]
A  B  C  D 
Die shopt Option localvar_inherit ist per default off. Falls sie aktiviert wird, können lokale Variable in einer Funktion den Wert aus vorheriger Umgebung erben.

Beispiel:

$ cat  aA-inherit
#!/bin/bash
  
A() { 
      local a 
      echo "A(): a=$a"
      echo  "# Setting a to 100:"
      a=100 
      echo "A(): a=$a"
}

a=1
echo "$0: a=$a"
A
echo "$0: a=$a"

echo "# shopt -s localvar_inherit"
shopt -s localvar_inherit

# nun wird die Variable a von der Funktion A geerbt:
A

# die Variable a bleibt in der Basis erhalten:
echo "$0: a=$a"
 

Funktionsaufruf:

$ bash aA-inherit 

aA-inherit: a=1
A(): a=
# Setting a to 100:
A(): a=100
aA-inherit: a=1
# shopt -s localvar_inherit
A(): a=1
# Setting a to 100:
A(): a=100
aA-inherit: a=1 
Alle weiteren shopt-Optionen können in den Man Pages nachgelesen werden.

Fazit

Es gibt einige ganz interessante neue Features mit Bash 5.0., z.B.die Möglichkeit, beim buildin-Kommando history ganze Bereiche löschen zu können. Im Vergleich zu der Menge der mit der Version 4 eingeführten Neuerungen ist es aber aktuell noch deutlich weniger …

Es wurden aber auch einige Fehler behoben, die im Laufe der Jahre festgestellt wurden (siehe z.B. www.git.savanah.gnu.org) Es wird noch einige Zeit dauern bis auf allen Linux Distributionen bash 5.0 zur Verfügung steht, da typischerweise gewartet wird, bis sich die Stabilität der Version etabliert hat. Eine der aktuell wenigen Ausnahmen ist "Debian GNU/Linux" der VERSION 10 (buster).

Ansonsten kann man sich die neue Version aus dem Git-Repository hier herunterladen und auf dem System kompilieren und installieren.
 

Kommentare

Derzeit gibt es keine Kommentare. Schreibe den ersten Kommentar!
Gäste
Sonntag, 08. Dezember 2019

Sicherheitscode (Captcha)