[fli4l] Nur #!/bin/sh oder auch #!/bin/bash?
Christoph Schulz
fli4l at kristov.de
Di Jan 31 14:00:08 CET 2017
Hallo!
K. Dreier schrieb:
> Da es
> nun doch scheinbar ein paar Unterschiede gibt (z.B. "``" für sh vs "()"
> für bash)
Das ist ein Irrglaube. Beides funktioniert wunderbar mit sh, bash und auch
der ash auf dem fli4l (siehe unten). Die $(...)-Schreibweise hat allerdings
den Vorteil, dass man sich nicht um das Entwerten von `-Anführungsstrichen
kümmern muss, will heißen,
# für die Fakultäts-Funktion siehe unten!
echo $(seq $(factorial 1) $(factorial 2))
ist einfacher zu schreiben als:
echo `seq \`factorial 1\` \`factorial 2\``
> Kurzum: kann ich auf fli4l (4.0-testing) in Skripten #!/bin/bash
> nutzen?
Ja und nein.
Syntaktisch kannst du _nicht_ "#!/bin/bash" in dein Skript schreiben, weil
es diesen Interpreter auf dem fli4l einfach nicht gibt.
Aber auf dem fli4l läuft die "ash", und diese unterstützt viele wichtige
(aber nicht alle) bash-Funktionen. Diese Shell ist unter /bin/sh zu finden,
so dass du in deine Skripte auf dem fli4l einfach
#!/bin/sh
in die erste Zeile schreiben und die erweiterten Funktionen der ash nutzen
kannst.
Allerdings ist mir keine Auflistung o.ä. bekannt, die zusammenfasst, welche
Funktionen der bash in der ash funktionieren und welche nicht. Ich fasse mal
einige Dinge zusammen, die mir direkt einfallen und auf dem fli4l
funktionieren:
### Variablen ###
# Wert von A
fence 4.0.0-r47062 # A="abc"
fence 4.0.0-r47062 # echo $A
abc
fence 4.0.0-r47062 # echo ${A}
abc
# ":-" : Wert von A, aber Alternative "x" falls leer oder undefiniert
fence 4.0.0-r47062 # unset A
fence 4.0.0-r47062 # echo ${A:-x}
x
fence 4.0.0-r47062 # A=""
fence 4.0.0-r47062 # echo ${A:-x}
x
# ":+" : Leere Zeichenkette, falls A leer oder undefiniert,
# aber Alternative "x" sonst (d.h. Ersetzung von A falls A nicht leer)
fence 4.0.0-r47062 # unset A
fence 4.0.0-r47062 # echo ${A:+y}
fence 4.0.0-r47062 # A=""
fence 4.0.0-r47062 # echo ${A:+y}
fence 4.0.0-r47062 # A="x"
fence 4.0.0-r47062 # echo ${A:+y}
y
# "+" : Leere Zeichenkette, falls A undefiniert, aber Alternative "x" sonst
# (d.h. Ersetzung von A falls A definiert und nicht leer)
fence 4.0.0-r47062 # unset A
fence 4.0.0-r47062 # echo ${A+y}
fence 4.0.0-r47062 # A=""
fence 4.0.0-r47062 # echo ${A+y}
y
fence 4.0.0-r47062 # A="x"
fence 4.0.0-r47062 # echo ${A+y}
y
# ":?" : Wert von A, falls A nicht leer, aber Fehlermeldung "y" sonst
fence 4.0.0-r47062 # unset A
fence 4.0.0-r47062 # echo ${A:?y}
-sh: A: y
fence 4.0.0-r47062 # A=""
fence 4.0.0-r47062 # echo ${A:?y}
-sh: A: y
fence 4.0.0-r47062 # A="x"
fence 4.0.0-r47062 # echo ${A:?y}
x
# "?" : Wert von A, falls A definiert, aber Fehlermeldung "y" sonst
fence 4.0.0-r47062 # unset A
fence 4.0.0-r47062 # echo ${A?y}
-sh: A: y
fence 4.0.0-r47062 # A=""
fence 4.0.0-r47062 # echo ${A?y}
fence 4.0.0-r47062 # A="x"
fence 4.0.0-r47062 # echo ${A?y}
x
# ":=" : Variableninhalt ersetzen, falls leer oder undefiniert
fence 4.0.0-r47062 # unset A
fence 4.0.0-r47062 # echo ${A}
fence 4.0.0-r47062 # echo ${A:=x}
x
fence 4.0.0-r47062 # echo ${A}
x
### Zeichenketten ###
fence 4.0.0-r47062 # A="abcdefabcdef"
## Teilzeichenketten ##
# Präfix abschneiden
fence 4.0.0-r47062 # echo ${A#abc}
defabcdef
fence 4.0.0-r47062 # echo ${A#*d}
efabcdef
fence 4.0.0-r47062 # echo ${A##*d}
ef
# Suffix abschneiden
fence 4.0.0-r47062 # echo ${A%def}
abcdefabc
fence 4.0.0-r47062 # echo ${A%c*}
abcdefab
fence 4.0.0-r47062 # echo ${A%%c*}
ab
# Teilwort extrahieren
fence 4.0.0-r47062 # echo ${A:2}
cdefabcdef
fence 4.0.0-r47062 # echo ${A:2:3}
cde
## Suchen und Ersetzen ##
# Erstes Vorkommen ersetzen
fence 4.0.0-r47062 # echo ${A/b/x}
axcdefabcdef
# Alle Vorkommen ersetzen
fence 4.0.0-r47062 # echo ${A//b/x}
axcdefaxcdef
### Rechnen ###
fence 4.0.0-r47062 # B=10
# Ausdrücke mit Variablen
fence 4.0.0-r47062 # echo $((5*B+7))
57
# Ausdrücke mit Variablen, die Ausdrücke (mit Variablen) beinhalten
fence 4.0.0-r47062 # C=B+2
fence 4.0.0-r47062 # echo $C
B+2
fence 4.0.0-r47062 # echo $((C))
12
fence 4.0.0-r47062 # echo $((5*C+7))
67
### Funktionen ###
# Fakultät mit Iteration (Schleife) und lokalen Variablen
fence 4.0.0-r47062 # function factorial() {
local result=1 i=$1
while [ $i -ne 0 ]; do
result=$((result * i))
i=$((i - 1))
done
echo $result
}
fence 4.0.0-r47062 # factorial 0
1
fence 4.0.0-r47062 # factorial 5
120
# Fakultät mit Iteration (seq) und lokalen Variablen
fence 4.0.0-r47062 # function factorial() {
local result=1 i
for i in $(seq 1 $1); do # hier könnte `seq ...` statt $(seq ...) stehen!
result=$((result * i))
done
echo $result
}
fence 4.0.0-r47062 # factorial 0
1
fence 4.0.0-r47062 # factorial 5
120
# Fakultät mit Rekursion (ganz ohne Variablen)
fence 4.0.0-r47062 # function factorial() {
if [ $1 -eq 0 ]; then
echo 1
else
echo $(($1 * $(factorial $(($1 - 1)))))
fi
}
fence 4.0.0-r47062 # factorial 0
1
fence 4.0.0-r47062 # factorial 5
120
Was die ash definitiv nicht unterstützt, sind die folgenden Konstrukte
- [[ ... ]] (Auswertung bedingter Ausdrücke;
nur außerhalb der Shell, keine Operatoren wie =~)
- (( ... )) (spezielle Auswertung numerischer Ausdrücke)
- <( ... ), >( ...) (Prozess-Ersetzung)
- A=(1 2); echo ${A[1]} (Arrays)
- ${A^...}, ${A,...} (Änderung der Groß-/Kleinschreibung)
Viele Grüße,
--
Christoph Schulz
[fli4l-Team]
Mehr Informationen über die Mailingliste Fli4L