2017-06-12 7 views
2

Die Beispiele wurden auf einem Raspberry Pi 3 ausgeführt, auf dem die Version 2017-04-10 von Raspbian Jessie bis Anfang Juni 2017 aktualisiert wurde. Bash ist Version 4.3.30 (1).Warum wird ein Teil eines Bash-Arrays als Befehl ausgeführt?

Beim Experimentieren mit etwas Code kürzlich, fand ich, dass der Inhalt eines Bash-Array ausgeführt wurde. Zum Glück waren sie nicht gefährlich!

Hier ist eine einfache Funktion:

#!/bin/bash 
echo "y.sh starting" 
echo "parameter string is <[email protected]>" 
args=([email protected]) 
echo "args array is <${args[@]}>" 
echo "args array length is ${#args[@]}" 
echo "y.sh ending" 

und hier ist der Ausgang

[email protected]:~ $ ./y.sh 
y.sh starting 
parameter string is <> 
args array is <> 
args array length is 0 
y.sh ending 
[email protected]:~ $ ./y.sh ls 
y.sh starting 
parameter string is <ls> 
args array is <ls> 
args array length is 1 
y.sh ending 

nichts Unerwartetes oben hier.

Nach Zugabe der y * Parameter, der Befehl ls Ausgang erscheint in der Array:

[email protected]:~ $ ./y.sh ls y* 
y.sh starting 
parameter string is <ls y01.sh y02.sh y03.sh y04a.sh y04.sh y.sh ytq> 
args array is <ls y01.sh y02.sh y03.sh y04a.sh y04.sh y.sh ytq> 
args array length is 8 
y.sh ending 

aber wenn -la hinzugefügt wird, gibt es keine Anzeichen für die zusätzlichen Informationen

[email protected]:~ $ ./y.sh ls -la y* 
y.sh starting 
parameter string is <ls -la y01.sh y02.sh y03.sh y04a.sh y04.sh y.sh ytq> 
args array is <ls -la y01.sh y02.sh y03.sh y04a.sh y04.sh y.sh ytq> 
args array length is 9 
y.sh ending 

Es wäre sehr hilfreich, wenn jemand erklären könnte, warum der Befehl ausgeführt wird und welche Änderungen vorgenommen werden können, damit er nicht ausgeführt wird. Eine Erklärung, warum die "lange" Ausgabe von ls nicht erzeugt wird, wäre ebenfalls von Interesse.

Mit Dank aus dem Haus der Cheshire Cat.

Antwort

6

Sie führen ls -la y* nicht aus Sie übergeben Argumente an y.sh. Die erste ist ls, dann -la Dann werden alle Dateien, die der Glob y* zu jedem erweitert, sein eigener Parameter.

Sie führen also den Befehl nicht aus, aber der Glob wird von der Shell erweitert.

Das passiert, wenn Sie auch ls y* ausführen. Sie übergeben die Zeichenfolge y* nicht an ls. Stattdessen dehnt sich die Schale y* und legt jede Datei, die die glob als Argument an ls passt, so dass Sie wirklich

ls y01.sh y02.sh y03.sh y04a.sh y04.sh y.sh ytq 

laufen würde, wenn Sie

ls y* 

getippt Sie könnten den gleichen Effekt sehen andere Befehle auch verwenden. echo zum Beispiel wird jedes Argument, das es gegeben ist, drucken, so können Sie ls y* simulieren, indem Sie tun echo y* (obwohl Echo zeigt nicht den Inhalt der Verzeichnisse, die mit y beginnen)

+0

Vielen Dank. Ich habe versucht, den Ansatz von @ runlevel0 hier https://stackoverflow.com/questions/12711786/bash-convert-command-line-arguments-into-array zu verwenden und erkannte, dass das Problem auftrat, bevor die Funktion mit der Arbeit begann Parameterliste. Dies wies mich auf http://www.tldp.org/LDP/abs/html/globbingref.html hin, was auf Ihre Erklärung hinausläuft. Wie so oft ist die Ursache nicht dort, wo man es erwartet! – user8150417

+0

Da das Problem mit globbing außerhalb der Funktion auftritt, kann es durch nichts innerhalb der Funktion behoben werden. Die Antwort von @TaxpayerZombies auf diese Frage https: //ksearch.wordpress.com/2010/09/23/Wildcard-Expansion-Bash-Shell/wies in die richtige Richtung - Einstellung eines Alias, der Globbing kurz deaktiviert. 'alias y = 'setze -o noglob; yy'; yy() {~/y.sh" $ @ "; setze + o nglob;}' – user8150417

Verwandte Themen