Ich habe dieses Shell-Skript in einer Datei gespeichert: Es führt einige grundlegende String-Ersetzungen durch.
#!/bin/sh
html_file=$1
echo "html_file = $html_file"
substr=.pdf
pdf_file="${html_file/.html/.pdf}"
echo "pdf_file = $pdf_file"
Wenn ich es in die Kommandozeile einfüge, funktioniert es einwandfrei:
$ html_file="/home/max/for_pauld/test_no_base64.html"
echo "html_file = $html_file"
substr=.pdf
pdf_file="${html_file/.html/.pdf}"
echo "pdf_file = $pdf_file"
gibt
html_file = /home/max/for_pauld/test_no_base64.html
pdf_file = /home/max/for_pauld/test_no_base64.pdf
Das ist die Ausgabe von Echo oben - es funktioniert wie beabsichtigt.
Aber wenn ich das Skript aufrufe, mit
$ saucer "/home/max/for_pauld/test_no_base64.html"
Ich bekomme diese Ausgabe:
html_file = /home/max/for_pauld/test_no_base64.html
/home/max/bin/saucer: 5: /home/max/bin/saucer: Bad substitution
Verwendet mein Skript eine andere Version von Bash oder so? Muss ich meine Shebang-Linie ändern?
sh
undbash
. Ich werde es nachlesen. Wenn Sie sich die Mühe machen können, Ihren Kommentar in eine Antwort umzuwandeln, werde ich ihn als richtig markieren.#!/usr/bin/env bash
Sie also im Allgemeinen: als Ihren Wahnsinn und verwenden Sie nach Belieben positiv definierte Substitutionen, jedoch mit Einschränkungen in Bezug auf die Portabilität. Und lesen Sie: unix.stackexchange.com/a/48787/27616Antworten:
Was ist sh
sh
(oder die Shell Command Language) ist eine Programmiersprache, die vom POSIX-Standard beschrieben wird . Es hat viele Implementierungen (ksh88
,dash
, ...).bash
kann auch als Implementierung vonsh
(siehe unten) betrachtet werden.Da
sh
es sich um eine Spezifikation handelt, nicht um eine Implementierung,/bin/sh
handelt es sich um einen Symlink (oder einen festen Link) zu einer tatsächlichen Implementierung auf den meisten POSIX-Systemen.Was ist Bash?
bash
sh
Begonnen als -kompatible Implementierung (obwohl sie einige Jahre älter ist als der POSIX-Standard), hat sie im Laufe der Zeit jedoch viele Erweiterungen erhalten. Viele dieser Erweiterungen können das Verhalten gültiger POSIX-Shell-Skripte ändern, sodass es sichbash
nicht um eine gültige POSIX-Shell handelt. Es ist vielmehr ein Dialekt der POSIX-Shell-Sprache.bash
unterstützt einen--posix
Switch, der POSIX-konformer ist. Es wird auch versucht, POSIX nachzuahmen, wenn es als aufgerufen wirdsh
.sh = bash?
Wurde lange Zeit
/bin/sh
verwendet, um/bin/bash
auf die meisten GNU / Linux-Systeme zu verweisen . Infolgedessen war es fast sicher, den Unterschied zwischen den beiden zu ignorieren. Aber das hat sich in letzter Zeit geändert.Einige beliebte Beispiele für Systeme, auf
/bin/sh
die nicht verwiesen wird/bin/bash
(und auf die einige/bin/bash
möglicherweise gar nicht existieren), sind:sh
zudash
standardmäßig;initramfs
. Es wird dieash
Shell-Implementierung verwendet.pdksh
einen Nachkommen der Korn-Shell. FreeBSDsh
ist ein Abkömmling der ursprünglichen UNIX-Bourne-Shell. Solaris hat eine eigene,sh
die lange Zeit nicht POSIX-kompatibel war. Eine kostenlose Implementierung ist im Heirloom-Projekt verfügbar .Wie können Sie herausfinden, worauf
/bin/sh
Ihr System abzielt?Die Komplikation ist, dass es
/bin/sh
sich um eine symbolische oder eine harte Verbindung handeln kann. Wenn es ein symbolischer Link, ein tragbarer Weg , es zu lösen ist:Wenn es sich um eine harte Verbindung handelt, versuchen Sie es
Tatsächlich
-L
deckt das Flag sowohl Symlinks als auch Hardlinks ab, aber der Nachteil dieser Methode ist, dass sie nicht portierbar ist - POSIX mussfind
die-samefile
Option nicht unterstützen , obwohl sowohl GNU find als auch FreeBSD find sie unterstützen.Shebang Linie
Letztendlich liegt es an Ihnen, zu entscheiden, welche Sie verwenden möchten, indem Sie die Zeile «shebang» schreiben.
Z.B
wird verwenden
sh
(und auf was auch immer das hinweist),wird verwendet,
/bin/bash
wenn es verfügbar ist (und schlägt mit einer Fehlermeldung fehl, wenn dies nicht der Fall ist). Natürlich können Sie auch eine andere Implementierung angeben, zWelches zu verwenden
Für meine eigenen Skripte bevorzuge ich
sh
aus folgenden Gründen:bash
, muss es vorhanden seinsh
Auch die Verwendung bietet Vorteile
bash
. Seine Funktionen machen das Programmieren bequemer und ähneln dem Programmieren in anderen modernen Programmiersprachen. Dazu gehören lokale Variablen und Arrays mit Gültigkeitsbereich. Plainsh
ist eine sehr minimalistische Programmiersprache.quelle
/bin/sh
in der Tat ein Symlink zu ist/bin/dash
.Ergänzend zu der hervorragenden Antwort von @ Hunter.S.Thompson möchte ich darauf hinweisen, dass der nicht portable Teil des Skripts ist
Das
${variable/search/replace}
ist eine GNU-Erweiterung. Mit reinem POSIX können Sie dies jedoch leicht vermeiden:Nach Hunter ist dies die bessere Lösung, als den Shebang in zu ändern
#! /bin/bash
quelle