Sie müssen verstehen, wie Unix Ihre Eingabe interpretiert.
Die Standard-Unix-Shell interpoliert Umgebungsvariablen und so genannte Globs, bevor es die Parameter an Ihr Programm übergibt. Dies unterscheidet sich ein wenig von Windows, wodurch das Programm die Erweiterung interpretiert.
Versuchen Sie folgendes:
$ echo *
Diese alle Dateien wird Echo und Verzeichnisse im aktuellen Verzeichnis. Bevor der Befehl echo
ausgeführt wird, interpoliert die Shell den Wert *
, erweitert ihn und übergibt diesen erweiterten Parameter dann an Ihren Befehl. Sie können ihn in Aktion sehen, indem Sie diese:
$ set -xv
$ echo *
$ set +xv
Die set -xv
schaltet xtrace und ausführliche. Verbose gibt den eingegebenen Befehl zurück und xtrace echos der Befehl, der ausgeführt wird (dh nach der Shell-Erweiterung).
Jetzt versuchen Sie dies:
$ echo "*"
Beachten Sie, dass die glob Ausdruck aus der Schale etwas in Anführungszeichen setzen versteckt, und die Schale nicht erweitern kann.Versuchen Sie das:
Beachten Sie, dass die Shell Umgebungsvariablen in doppelte Anführungszeichen noch erweitern kann, aber nicht in einfache Anführungszeichen.
Kommen wir nun zu Ihrer Aussage aussehen:
file="home/edward/bank1/fiche/Test*"
Die doppelte Anführungszeichen verhindern, dass die Schale aus Erweiterung des glob Ausdruck, so file
gleich dem wörtlichen home/edward/bank1/finche/Test*
. Daher müssen Sie, dies zu tun: (! Und der einleitende slash was wichtig ist)
file=/home/edward/bank1/fiche/Test*
Das Fehlen von Zitaten wird nun Datei gleich alle Dateien, die diesen Ausdruck entsprechen. (Es könnte mehr als eins sein!). Wenn es keine Dateien gibt, kann die Shell, abhängig von der Shell und ihren Einstellungen, die Datei einfach auf diese literale Zeichenfolge setzen.
Sie haben sicherlich die richtige Idee:
file=/home/edward/bank1/fiche/Test*
if test -s $file
then
echo "found one"
else
echo "found none"
fi
aber man könnte noch erhalten keine gefunden zurückgegeben, wenn es mehr als eine Datei ist. Stattdessen erhalten Sie möglicherweise einen Fehler in Ihrem test
-Befehl, da zu viele Parameter vorhanden sind.
Eine Möglichkeit, dies zu umgehen könnte sein:
if ls /home/edward/bank1/finche/Test* > /dev/null 2>&1
then
echo "There is at least one match (maybe more)!"
else
echo "No files found"
fi
In diesem Fall nehme ich die Vorteile der Exit-Code des ls
Befehl. Wenn ls
eine Datei findet, auf die es zugreifen kann, gibt es einen Null-Beendigungscode zurück. Wenn keine übereinstimmende Datei gefunden werden kann, wird ein Beendigungscode ungleich null zurückgegeben. Der Befehl if
führt lediglich einen Befehl aus, und wenn der Befehl eine Null zurückgibt, nimmt er die if
-Anweisung als wahr an und führt die if
-Klausel aus. Wenn der Befehl einen Wert ungleich Null zurückgibt, wird angenommen, dass die if
-Anweisung falsch ist, und die else
-Klausel (falls eine verfügbar ist) wird ausgeführt.
Der Befehl test
funktioniert in ähnlicher Weise. Wenn test
wahr ist, gibt der test
Befehl eine Null zurück. Andernfalls gibt der Befehl test
einen Wert ungleich null zurück. Dies funktioniert hervorragend mit dem Befehl if
. In der Tat gibt es einen Alias zum test
Befehl. Versuchen Sie folgendes:
$ ls -li /bin/test /bin/[
Die i
druckt die inode. Die Inode ist die echte ID der Datei. Dateien mit derselben ID sind dieselbe Datei. Sie können sehen, dass /bin/test
und /bin/[
derselbe Befehl sind.Dies macht die folgenden zwei Befehle die gleiche:
if test -s $file
then
echo "The file exists"
fi
if [ -s $file ]
then
echo "The file exists"
fi
Die Frage "Shell" gibt - welche? Die Antwort, die ich hier für am besten halte, ist Bash-spezifisch; ist das angemessen oder zielst du auf etwas anderes? –