Ich programmiere ein Linux-Shell-Skript , das während seiner Ausführung nur Statusbanner druckt, wenn beispielsweise das richtige Tool verwendet wirdfiglet
, ist installiert (dies ist: erreichbar über Systempfad ).
Beispiel:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
Ich möchte, dass mein Skript auch dann fehlerfrei funktioniert , wennfiglet
es nicht installiert ist .
Was könnte eine praktische Methode sein ?
shell
scripting
executable
Sopalajo de Arrierez
quelle
quelle
figlet ... || true
.figlet || true
, aber in Ihrem Fall ist wahrscheinlich eine Shell-Funktion, die Echos-Klartext Wenn kein Banner gedruckt werden kann, eher das, was Sie wollen.Antworten:
Meine Interpretation würde eine Wrapper-Funktion verwenden, die den gleichen Namen hat wie das Tool. Führen Sie in dieser Funktion das eigentliche Tool aus, falls es vorhanden ist:
Dann können Sie
figlet arg1 arg2...
unverändert in Ihrem Skript haben.@Olorin hat eine einfachere Methode entwickelt: Definieren Sie eine Wrapper-Funktion nur, wenn dies erforderlich ist (falls das Tool nicht vorhanden ist):
Wenn Sie
figlet
möchten, dass die Argumente gedruckt werden, auch wenn das Figlet nicht installiert ist, passen Sie Olorins Vorschlag wie folgt an:quelle
command
her? Ich habe es nicht in meinen Installationen (Red Hat 6.8 Enterprise und Cygwin64).command
ist eine POSIX Bourne-Shell. Normalerweise führt es den angegebenen Befehl aus, aber das-v
Flag lässt es sich eher wie einetype
andere eingebaute Shell verhalten.type -a command
wird es dir zeigen.which
zeigt nur ausführbare Dateien auf Ihren$PATH
, keine eingebauten Schlüsselwörter, Funktionen oder Aliase.which
findet sich ein passender Alias, weil er sichwhich
selbst/usr/bin/which
als Aliase ansieht, um eine Liste der zu durchsuchenden Aliasnamen der Shell auszuleiten (!) (\which
Unterdrückt natürlich den Alias und verwendet nur das Programm, das keine AliaseSie können testen, ob
figlet
vorhandenquelle
Ein üblicher Weg, dies zu tun, ist mit
test -x
aka[ -x
. Hier ist ein Beispiel aus/etc/init.d/ntp
einem Linux-System:Diese Variante setzt voraus, dass der vollständige Pfad der ausführbaren Datei bekannt ist. In habe
/bin/lesspipe
ich ein Beispiel gefunden, das das umgeht, indem es-x
und denwhich
Befehl kombiniert :Auf diese Weise funktioniert dies, ohne vorher zu wissen, wo sich
PATH
diebunzip
ausführbare Datei befindet.quelle
which
. Und selbst wenn eswhich
funktioniert, ist die Verwendungtest -x
der Ausgabe dumm: Wenn Sie einen Pfad abrufenwhich
, ist er vorhanden.test -x
es mehr als nur zu überprüfen, ob eine Datei existiert (wofürtest -e
ist das gedacht ). Es wird auch geprüft, ob die Datei über die festgelegten Ausführungsberechtigungen verfügt.which
.Überprüfen Sie zu Beginn Ihres Skripts,
figlet
ob es eine Shell-Funktion gibt. Wenn dies nicht der Fall ist, definieren Sie eine Shell-Funktion, die nichts bewirkt:type
Überprüft, obfiglet
eine integrierte Shell, eine Funktion, ein Alias oder ein Schlüsselwort vorhanden ist,>/dev/null 2>&1
verwirft stdin und stdout, sodass Sie keine Ausgabe erhalten, undfiglet() { :; }
definiertfiglet
als eine Funktion, die nichts tut , wenn sie nicht vorhanden ist .Auf diese Weise müssen Sie nicht jede Zeile Ihres Skripts bearbeiten
figlet
oder jedes Mal prüfen, ob sie vorhanden istfiglet
Aufruf ist.Sie können eine Diagnosemeldung hinzufügen, wenn Sie möchten:
Als Bonus, da Sie nicht erwähnt haben, welche Shell Sie verwenden, glaube ich, dass dies POSIX-kompatibel ist, so dass es auf fast jeder Shell funktionieren sollte.
quelle
type figlet >/dev/null 2>&1
mit ,hash figlet 2>/dev/null
wenn Sie bash verwenden. (Das OP sagte "wenn es in meinem WEG ist".)Eine weitere Alternative - ein Muster, das ich in Skripten zur automatischen Konfiguration von Projekten gesehen habe:
In Ihrem speziellen Fall könnten Sie sogar tun,
Wenn Sie den spezifischen Pfad nicht kennen, können Sie mehrere
elif
(siehe oben) ausprobieren, um bekannte Speicherorte zu ermitteln, oder einfach die verwendenPATH
, um den Befehl immer aufzulösen:Im Allgemeinen bevorzuge ich beim Schreiben von Skripten das Aufrufen von Befehlen nur an bestimmten von mir angegebenen Stellen. Ich mag nicht die Ungewissheit / das Risiko, was der Endbenutzer in seine
PATH
, vielleicht in seine, investiert hat~/bin
.Wenn ich zum Beispiel ein kompliziertes Skript für andere schreibe, das möglicherweise Dateien basierend auf der Ausgabe eines bestimmten Befehls, den ich aufrufe, entfernt, möchte ich nicht versehentlich etwas in ihrem Skript aufgreifen, das möglicherweise
~/bin
der Befehl ist oder nicht Ich erwartete.quelle
figlet
in/usr/local/bin
oder/home/bob/stuff/programs/executable/figlet
?Der bash-
type
Befehl findet einen Befehl, eine Funktion, einen Alias, ein Schlüsselwort oder eine integrierte Funktion (siehehelp type
) und gibt den Speicherort oder die Definition aus. Es gibt auch einen Rückkehrcode zurück, der das Ergebnis der Suche darstellt. true (0) falls gefunden. Wir versuchen hier also,figlet
im Pfad zu suchen (-p
dh nur nach Dateien zu suchen, nicht nach eingebauten Dateien oder Funktionen, und Fehlermeldungen zu unterdrücken), die Ausgabe zu verwerfen (das ist es, was es> /dev/null
tut) und wenn es true (&&
) zurückgibt wird ausgeführtfiglet
.Dies ist einfacher, wenn Sie
figlet
sich an einem festen Ort befinden:Hier verwenden wir den
test
Befehl (aka[
), um zu sehen, ob er/usr/bin/figlet
ausführbar ist (-x
) und führen ihn gegebenenfalls aus (&&
). Diese Lösung ist meiner Meinung nach portabler als die Verwendung,type
was meiner Meinung nach ein Bashismus ist.Sie könnten eine Funktion erstellen, die dies für Sie erledigt:
(Die Anführungszeichen sind wegen möglicher Leerzeichen notwendig)
Dann machen Sie einfach:
quelle
o / ich würde sowas sagen
quelle
Sie können eine Testausführung durchführen, jede Ausgabe unterdrücken und den Erfolgs- / Fehlercode testen. Wählen Sie Argumente aus, um diesen Test kostengünstig zu gestalten. -? oder --help oder --version sind offensichtliche Möglichkeiten.
Als Antwort auf den Kommentar unten hinzugefügt: Wenn Sie wirklich testen möchten, ob das Figlet existiert, und nicht, ob es verwendbar ist, würden Sie dies tun
quelle
$?
127 (auf meinem Linux-System) entspricht. 127 ist "Befehl nicht gefunden". Aber ich denke, dass bei rationalen Befehlencommand --help
die Installation bei einem Fehlschlag so weit verzweigt ist, dass sie auch nicht vorhanden sein könnte !.--help
, verfügbar zu sein. Posix-Dienstprogramme haben es nicht, und die Posix-Richtlinien empfehlen es tatsächlich .at --help
scheitertat: invalid option -- '-'
zum Beispiel mit und einem Exit-Status von130
auf meinem System.-?
--help
--version
... oder Sie könnten herausfinden, was damit herauskommtfiglet -0 --illegal
, und dies als Ihren Erfolgsindikator behandeln (solange es nicht 127 ist, was ich klassifizieren würde) als Sabotage).