Bash-Skript

Bash-Skript

Ich lese das Bash-Skript und verstehe nicht, was da vor sich geht.

#!/bin/sh
[ x$1 = x ] 

Was passiert in der zweiten Zeile und was [ x$1 = x ] bedeutet das?

Antwort1

Damit wird geprüft, ob das $1leer ist, obwohl es in Anführungszeichen gesetzt werden sollte (identisch mit [ -z "$1" ]). Einige sehr alte Shells konnten leere Zeichenfolgen nicht richtig verarbeiten, daher übernahmen die Autoren portabler Skripte diese Art der Prüfung. Das ist seit Jahrzehnten nicht mehr nötig, aber die Leute machen es immer noch so, weil die Leute es immer noch so machen.

Antwort2

Eckige Klammern kennzeichnen eineprüfen, also [ x$1 = x]ohne ifoder etwas ähnliches ist bedeutungslos, obwohl syntaktisch ok.

Es soll als „true“ ausgewertet werden, wenn x$1es zu erweitert wird x, und andernfalls als „false“, da es aber nicht in Anführungszeichen steht und $1die Shell beispielsweise „hey x“ sieht x = x, ist diese Konstruktion trotzdem nicht sicher.

Der Zweck der x = xPrüfung besteht darin, festzustellen, ob eine Variable leer ist. Eine gängigere Methode hierfür wäre die Verwendung von Anführungszeichen:

if [ "$1" = "" ]; then

Bash-Testoperatoren können -zebenfalls -nverwendet werden, sind aber weniger auf andere Shell-Typen portierbar. 1

Der Grund für die Anführungszeichen bzw. das x$1besteht darin, dass die linke Seite nicht ins Leere laufen soll, was ein syntaktischer Fehler wäre:

if [  = x ]  # No good!
if [ "" =  "" ] # Okay.
if [ x = x ] # Also okay.

1. Eigentlich testkann es ein eigenständiges Dienstprogramm sein, aber die meisten Shells implementieren es als integriertes Dienstprogramm. Überprüfen Sie den Unterschied zwischen which testund type test. Unter GNU/Linux man testwird behauptet, sich auf das integrierte Dienstprogramm zu beziehen, aber wenn Sie (zB) aufrufen /usr/bin/test, scheint dieses Dienstprogramm die in der Manpage dokumentierten Funktionen zu implementieren, einschließlich -zund -n.

Antwort3

[ x$1 = x ]

Macht nur in Sinn zsh. Dabei wird die Verkettung von xmit dem ersten Argument des Skripts mit verglichen x. Der [Befehl gibt also true zurück, wenn $1leer ist oder nicht angegeben wurde.

[ $1 = "" ]

Würde nicht funktionieren, weil zsheine leere Variable, wenn sie in Listenkontexten nicht in Anführungszeichen gesetzt ist, zu gar keinem Argument anstatt zu einem leeren Argument erweitert wird. Wenn sie also $1nicht gesetzt oder leer wäre, [würde der Befehl als Argumente nur [, =, den leeren String und erhalten ], mit dem er keinen Sinn erkennen könnte. [ -z "$1" ]Oder [ "$1" = "" ]wäre OK, wie in POSIX-Shells.

In Bourne-ähnlichen/POSIX-Shells [ x$1 = x ]ergibt das keinen Sinn. Das ist der Split+Glob-Operator, der irgendwie auf die Verkettung von xund dem ersten Argument des Skripts angewendet wird, in der Hoffnung, dass das Ergebnis und =und x, und ]einen gültigen Testausdruck für den Befehl ergeben [.

Wenn dem Skript beispielsweise ein " = x -o x ="Argument übergeben würde, [würde es diese Argumente erhalten: [, x, =, x, -o, x, =, x, ], was als Vergleich mit und mit [verstanden würde und „true“ zurückgeben würde.xxxx

Wenn , würde die Shell dem Befehl die Liste der Dateien im aktuellen Verzeichnis übergeben, deren Name mit (der Glob-Erweiterung von ) beginnt, dann die Liste der nicht versteckten Dateien (Erweiterung ) …, was wahrscheinlich keinen Sinn ergibt. Die einzigen Fälle, in denen dies etwas Sinnvolles bewirken würde, sind, wenn $1keine Platzhalter oder Leerzeichen enthalten sind."* *"[xx**[$1

Manchmal findet man Code wie den folgenden:

[ "x$1" = x ]

Dies wird verwendet, um zu testen, ob $1es leer oder nicht gesetzt ist.

Die normale Vorgehensweise zum Testen, ob eine Variable leer oder nicht gesetzt ist, ist:

[ -z "$1" ]

Dies schlägt jedoch bei einigen Werten fehl, $1beispielsweise =bei einigen (nicht-POSIX-) [Implementierungen, beispielsweise bei der integrierten in der Bourne-Shell, wie sie /bin/shunter Solaris 10 und früher oder einigen alten Versionen von dash(bis 0.5.4) oder sheinigen BSDs zu finden ist.

Das liegt daran, dass , , , [sieht und sich über fehlende Argumente des binären Operators beschwert, anstatt ihn als den auf die Zeichenfolge angewendeten unären Operator zu verstehen .[-z=]=-z=

Ebenso [ "$1" = "" ]schlägt bei einigen Implementierungen von [if $1is !oder fehl (.

In diesen Shell/ [Implementierungen:

[ "x$1" = x ]

ist immer ein gültiger Test, unabhängig vom Wert von $1. Das gilt auch für:

[ "" = "$1" ]

Und:

[ -z "${1:+x}" ]

Und

case $1 in "") ...; esac

Wenn Sie überprüfen möchten, dass kein Argument angegeben ist, gehen Sie natürlich wie folgt vor:

[ "$#" -eq 0 ]

Das heißt, Sie überprüfen die Anzahl der an das Skript übergebenen Argumente.

Beachten Sie, dass heutzutage von POSIX eindeutig spezifiziert ist und in konformen Implementierungen [ -z "$var" ]nicht fehlschlagen kann (und dies ist seit Jahrzehnten der Fall). Sie sollten sich also in POSIX-sh oder -Skripten darauf verlassen können.[bash[bash

Antwort4

[ x$1 = x ]ist wahr, wenn $1nicht gesetzt/null/leer ist oder nicht.
Probieren Sie es selbst mit:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
und
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"

verwandte Informationen