Binäroperator erwartet – Anführungszeichen für Shell-Skript-Argumente

Ich habe eine Frage, wie ich beim Ausführen eines Shell-Skripts Argumente hinzufüge.

Ich habe ein einfaches Skript, mit dem ich IP-Bereiche blockieren kann:

/ block_ip.sh:

if [ ! $3 ] then echo "usage ~/block_ip.sh (DROP/ACCEPT) "0.0.0.0" "amsterdam"" exit 1 fi echo "adding $3" sudo iptables -I INPUT -s $2 -j $1 -m comment --comment "$3" 

Wenn ich dies ohne Argumente ausführe, ist die Ausgabe wie erwartet:

~$ ./block_ip.sh usage ~/block_ip.sh (DROP/ACCEPT) "0.0.0.0" "amsterdam" 

Die Leerzeichen scheinen jedoch die Ursache für die zu sein unerwartete Ausgabe von „Binäroperator erwartet“ :

~$ ./block_ip.sh DROP "1.0.0.0/8" "south brisbane qld" ./block_ip.sh: line 1: [: brisbane: binary operator expected adding south brisbane au 

Aber dann wird sie trotz der unerwarteten Ausgabe hinzugefügt:

Chain INPUT (policy ACCEPT) num target prot opt source destination 1 DROP all -- 1.0.0.0/8 anywhere /* south brisbane au */ 

Wenn dies ein Anführungszeichen ist, wie bilde ich die Argumente (ohne Backslashes zu verwenden, um die Leerzeichen zu umgehen)? Natürlich erwarte ich möglicherweise eine Änderung Für das Skript ist dies ebenfalls eine akzeptable Lösung.

Kommentare

  • Wenn Ihr Ziel beim Testen von $3 ist nur, um sicherzugehen, dass es drei Parameter gibt Sie können die einfachere Shell-Variable $# verwenden, die die Anzahl der Parameter enthält, z. if [ $# -ne 3 ].

Antwort

Ja, das ist ein Zitat Problem: [ ! $3 ] wird auf [ ! south brisbane qld ] erweitert (vier Argumente zwischen [ und ]). Und wenn vier Argumente angezeigt werden, wobei das erste ein ! ist, erwartet [, etwas zu sehen wie [ ! arg1 op arg2 ] wobei op ein binärer Operator ist (dies ist wiederum eines der Dinge, die sich zwischen [ .. ] und [[ .. ]]; siehe dieses Q und Auch dieses Q )

brisbane ist kein gültiger Operator, daher beschwert es sich und gibt 2 zurück, was falsch ist, so dass die Anweisungen innerhalb des if werden nicht ausgeführt. Um den Unterschied zwischen einem Fehler und einem regulären Fehlertest zu erkennen, müssten Sie den Rückgabewert explizit gegen 2 testen.

Wenn $3 ist leer, dann wird der Test zu [ ! ], einem Ein-Argument-Test, der prüft, ob das einzige Argument nicht leer ist (es ist die Ein-Zeichen-Zeichenfolge !). In diesem Fall funktioniert es wie beabsichtigt, jedoch möglicherweise nicht aus dem Grund, den Sie erwarten würden.


Sie möchten [ ! "$3" ] oder [ -z "$3" ], um die Zeichenfolge als ein Argument für [ beizubehalten.

Natürlich können Sie auch den Sinn des Tests umkehren und das tun tatsächliche Arbeit innerhalb der if, so dass ein Fehler im Test das Ausführen der Hauptbefehle vermeiden würde. Dies würde jedoch die Codestruktur etwas unklarer machen.

Kommentare

  • nett – der Grund, warum es dann funktioniert, ist, dass $ 3 nicht ' nicht leer ist, obwohl es fehlerhaft ist Besteht den! -Test und dann habe ich ihn im Befehl iptables zitiert, sodass seine Erweiterung um Leerzeichen bereits behandelt wird – stimmt das?
  • und sie ' Ich möchte auch die Parameter in der iptables-Zeile zitieren.
  • @WEBjuju, ah ja, ich wollte darüber schreiben, bearbeitet, warum es funktioniert. Und ja,Sie hatten die Anführungszeichen im Befehl iptables, damit es dort gut funktioniert.
  • @ilkkachu gotcha, ja, es scheint mir albern. Irgendwie wusste ich es unbewusst, konnte aber ' das Wissen nicht zu einer funktionierenden Lösung bringen. Ich bin irgendwie durcheinander geraten, ohne diesen Grundmieter bis jetzt zu kennen, aber ich bin nur ernsthaft aufgestiegen. Vielen Dank!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.