Bash, Warnung ohne Argumente und Fallentscheidungen

110

Ich lerne Bash.

Ich möchte ein einfaches Skript erstellen, das, wenn keine Argumente angegeben werden, eine Meldung anzeigt. Und wenn ich Zahlen als Argument gebe, s abhängig vom Wert, macht es die eine oder andere Sache.

Ich würde auch gerne Vorschläge für die besten Online-Handbücher für Anfänger in Bash wissen

Vielen Dank

Mach den Weg frei
quelle

Antworten:

176
if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 0
fi

case "$1" in
    1) echo 'you gave 1' ;;
    *) echo 'you gave something else' ;;
esac

Das Advanced Bash-Scripting Guide ist ziemlich gut. Trotz seines Namens behandelt es die Grundlagen.

Thomas
quelle
RE: "exit 0". Ich weiß nicht, ob er daran gedacht hatte, das Drehbuch zu verlassen. Aber ja, das ist ein ausgezeichneter Leitfaden.
Trampas Kirk
Ich interpretierte "und" als "anders", vorausgesetzt, die Nachricht wäre ein Hilfetext. Aber ich bin sicher, Werner ist in der Lage herauszufinden, was diese Linie tut und ob er es will :)
Thomas
danke natürlich! Und als letztes, wie kann ich Fehlermeldungen im Skript deaktivieren, damit sie der Shell nicht angezeigt werden?
Öffnen Sie den Weg
Sie meinen die Fehler, die von einem bestimmten Programm ausgehen, das Sie aufrufen? Sie können setzen > /dev/nullund / oder 2> /dev/nulldanach, um die Standardausgabe und / oder Standardfehlerströme in Vergessenheit zu geraten.
Thomas
4
Wenn Sie ein fehlendes Argument für etwas Schlechtes halten (wie das Skript dann nicht erfolgreich ausgeführt werden kann), geben Sie etwas anderes als 0 ( exit 1) zurück. Es gibt weitere Konventionen zu Rückgabe- / Ausstiegscodes, die Sie schnell online finden können. Wichtig ist jedoch, dass sie nicht 0 sein sollten, was auf Erfolg hinweist.
Felix
25

Wenn Sie nur dann an einer Kaution interessiert sind, wenn ein bestimmtes Argument fehlt, ist die Parametersubstitution großartig:

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT
Klopfen
quelle
11

Beispiel

 if [ -z "$*" ]; then echo "No args"; fi

Ergebnis

No args

Einzelheiten

-z ist der unäre Operator für die Länge der Zeichenfolge ist Null. $*ist alles Argumente. Die Anführungszeichen dienen der Sicherheit und enthalten mehrere Argumente, falls vorhanden.

Verwenden Sie man bashund suchen Sie ( / key) nach "unary" für weitere Operatoren wie diesen.

Trampas Kirk
quelle
7
Ein (geringfügiges) Problem dabei ist, dass nicht zwischen der Übergabe keiner Argumente und der Übergabe einer leeren Zeichenfolge als Argument unterschieden wird. Das kann in einigen Zusammenhängen wichtig sein. Mit [$ # -eq 0] kann man beide Fälle richtig behandeln.
Idelic
1
Ah, die Feinheiten der (ba) sh-Programmierung ... Deshalb hasse ich es.
Thomas
1
denken -zals mizzing
Ray Foss
4

Alt, aber ich habe Grund, die Antwort jetzt zu überarbeiten, dank einiger vorheriger Verwirrung:

if [[ $1 == "" ]] #Where "$1" is the positional argument you want to validate 

 then
 echo "something"
 exit 0

fi

Dies gibt "Something" aus, wenn kein Positionsargument $ 1 vorhanden ist. Es wird jedoch nicht überprüft, ob $ 1 bestimmte Informationen enthält.

Ryan Smith
quelle
$#ist explizit die Ganzzahl der Anzahl der Argumente; Es wird entweder "0" sein und Sie werden "etwas" wiedergeben, obwohl es keine Argumente gibt, oder es wird eine positive Zahl sein, und Sie werden "etwas" korrekt wiedergeben. Die Prüfung selbst wird jedoch niemals etwas bewirken, unabhängig von der Eingabe oder dem Mangel an Eingabe, die Sie verwenden. Es wird immer gemeldet, dass $#ein Wert enthalten ist. Das ist also völlig falsch und wird niemals wie behauptet funktionieren.
Eschwartz
Sind Sie sich dessen völlig sicher? Ich habe mehrere Skripte, die mit genau diesem Format wie beabsichtigt funktionieren. Nachdem ich Ihre Antwort gelesen hatte, testete ich sie erneut auf das Spiel und das Fehlen davon. $ # enthält keinen Wert, wenn nicht angegeben, wenn es kein Positionsargument gibt, das mit dem # in Ihrem Szenario übereinstimmt. Es macht keinen Sinn, warum bash einen Wert in einem Positionsargument annehmen würde, das nicht vorhanden ist.
Ryan Smith
Versuchen Sie es echo $#als Inhalt eines Skripts /tmp/test.sh, und führen Sie es dann unter / bin / bash sowie / bin / sh (oder / bin / dash und allen anderen verfügbaren Shell-Implementierungen aus. /tmp/test.shGibt "0" aus Die Konsole wird /bin/dash /tmp/test.shauf der anderen Seite /tmp/test.sh foo"1" und /tmp/test.sh first second"2" wiedergeben.
eschwartz
Gemäß man bashdem Abschnitt "Spezielle Parameter" behandelt "Die Shell behandelt mehrere Parameter speziell. Diese Parameter dürfen nur referenziert werden; eine Zuordnung zu ihnen ist nicht zulässig." Und "# Erweitert sich auf die Anzahl der Positionsparameter in Dezimalzahl." Es wird ebenfalls von POSIX beauftragt, wie in pubs.opengroup.org/onlinepubs/9699919799/utilities/…
eschwartz am
Tut mir leid, es gab eine Fehlkommunikation! Ich meinte # als Platzhalter für das spezifische Positionsargument (dh $ 2, wenn Sie das zweite Argument meinten), nicht wörtlich $ #. Nachdem Sie Ihre obigen Angaben überprüft haben, sind Sie absolut korrekt. Ein Literal $ # wird immer in die Anzahl der Argumente aufgelöst. Entschuldigung für die Verwirrung.
Ryan Smith