Bash erkennt Funktionsargument als Programm

Bash erkennt Funktionsargument als Programm

Ich bin ziemlich neu in der Syntax von Bash und habe einen Codeabschnitt in meiner Datei „.bash_aliases“. Er erhält entweder eine Ganzzahl als Argument oder den Buchstaben „c“. Wenn er eine Ganzzahl erhält, legt er diese Ganzzahl in eine Umgebungsvariable, die von Webservern als Port verwendet werden kann. Wenn er den Buchstaben „c“ als Eingabe erhält, löscht er die Variable.

Wenn ich versuche, meinen Befehl mit einer Ganzzahl auszuführen, erhalte ich den Fehler

main@linuxWSL:~$ serverp 2000
-bash: [: missing `]'
2000: command not found

und wenn ich es mit dem Buchstaben 'c' versuche, bekomme ich

main@linuxWSL:~$ serverp c
-bash: [: missing `]'
c: command not found

Dies ist mein Bash-Code:

serverp () {
  if [ "$1" = "clear" || "$1" = "c" ]
  then
    unset PORT
    echo -e "\e$CLEAR$GREEN""mWebServer port has been reset!""$CLEAN"
    return 0
  fi

  export PORT="$1"
}

Kann mir jemand helfen? Danke!

Antwort1

[ist kein Schlüsselwort in Bash, das dazu führen würde, dass der Shell-Parser den Rest der Befehlszeile anders interpretiert. [ist ein Befehl wie catoder echo. [(wie echo) ist in Bash integriert, aber das bedeutet nur, dass es ausgeführt werden kann, ohne einen zusätzlichen Prozess zu erzeugen, es verhält sich dennoch wie ein Befehl.

Und um es klarzustellen: [ … ]ist kein Teil der if … then …Syntax. iftestet lediglich den Beendigungsstatus von Code: if true; then …ist gültig, if sleep 5; then …ist gültig, ebenso if [ … ]; then …ist gültig (wenn der [ … ]Teil selbst ein gültiger Befehl ist).

[Auf Ihrem System befindet sich wahrscheinlich eine ausführbare Datei. Versuchen Sie type -a [es mit . Vergleichen Sie mit type -a [[. Im Gegensatz zu ist [, [[ein Schlüsselwort in Bash und es veranlasst den Parser, Dinge zwischen [[und ]]speziell zu behandeln.

[ist kein Schlüsselwort. Richtig geschrieben [ … ]ist dies ein Befehl, bei dem ]nur das letzte Argument ist. [erfordert ]als letztes Argument, sonst funktioniert es nicht. Dies dient nur dazu, es [ … ]als Block hervorzuheben, als ob es eine spezielle Syntax wäre; es ist aber keine spezielle Syntax.

Ihr [ "$1" = "clear" || "$1" = "c" ]wird von der Shell als interpretiert [ "$1" = "clear"und "$1" = "c" ]mit verbunden ||. Es gibt also zwei Befehle. Der erste Befehl ist [ "$1" = "clear", der [wird ausgeführt, er erhält nicht ]als letztes Argument, er beschwert sich und wird mit einem Exit-Status ungleich Null beendet. Wegen des Status ungleich Null und wegen ||versucht die Shell, den zweiten Befehl auszuführen, der mit dem beginnt, was auch immer "$1"sich zu erweitert. Auf diese Weise wird das erste Argument Ihres Skripts als ausführbare Datei interpretiert, die ausgeführt werden soll.

Beheben Sie [ … || … ]das Problem folgendermaßen:

[ "$1" = "clear" ] || [ "$1" = "c" ]

Dieser Ausschnitt besteht aus zweigültig [Befehle. Es sollte tun, was Sie wollen.

Beachten Sie [[ "$1" = "clear" || "$1" = "c" ]], dass es sich um einen funktionierenden Code handelt, während [ "$1" = "clear" || "$1" = "c" ]es sich nicht um einen handelt. Dies liegt daran , dass [[es sich nicht um einen Befehl handelt. Es ist ein Schlüsselwort und veranlasst den Shell-Parser, alles bis zu ]]speziell zu behandeln; dazu gehört auch das ||. Es gibt noch andereUnterschiede zwischen [[und[, vertauschen Sie sie nicht blind.

Die [in Bash integrierte Unterstützung -ofüroder(und -afürUnd), also wird das hier auch funktionieren:

[ "$1" = "clear" -o "$1" = "c" ]

Es ist Ihr Code, in dem (speziell für die Shell) durch (nicht speziell für die Shell) ||ersetzt wurde . Sie sollten dies jedoch vermeiden. Von-o-oDieser Artikel:

Die Binärdateien -aund -o[…] sind XSI-Erweiterungen des POSIX-Standards. Alle sind in POSIX-2008 als veraltet gekennzeichnet. Sie sollten in neuem Code nicht verwendet werden. Eines der praktischen Probleme mit [ A = B -a C = D ](oder -o) ist, dass POSIX die Ergebnisse eines testoder [Befehls mit mehr als 4 Argumenten nicht angibt. Es funktioniert wahrscheinlich in den meisten Shells, aber Sie können nicht darauf zählen. Wenn Sie für POSIX-Shells schreiben müssen, sollten Sie stattdessen zwei testoder [Befehle verwenden, die durch einen &&Operator getrennt sind.

Beachten Sie, dass der Artikel näher auf eingeht -a, also „einen &&Operator stattdessen“. In Ihrem Fall sind es -obzw. ||Zwei durch einen Operator getrennte Tests ||sind genau unsere Lösung.

Antwort2

Es ist if [ "$1" = "clear" ] || [ "$1" = "c" ].

verwandte Informationen