Warum übergibt --text = "$ @" nur das erste Wort?

9

Wenn ich das folgende Skript mit einigen Argumenten wie arg1 arg2 arg3:

#!/bin/bash
zenity --entry --text="$@"

Zenity erstellt einen Eingabedialog mit diesem Text: "arg1", während ich "arg1 arg2 arg3" erwarte.

Wenn ich eine Variable wie das folgende Skript verwende, werden alle Argumente für den Eintragstext angezeigt.

#!/bin/bash
text="$@"
zenity --entry --text="$text"

Was ist der Unterschied zwischen diesen Skripten? Warum ersetzt $@das erste nur das erste Argument?

Omid
quelle

Antworten:

16

$@wird zu separaten Wörtern $*erweitert (während zu einem einzelnen Wort erweitert wird), wie im bashHandbuch erläutert . Also, wenn du schreibst

zenity --text="$@"

es erweitert sich zu

zenity --text="$1" "$2" "$3"

Zuweisungen von Shell-Variablen unterliegen jedoch keiner Wortaufteilung. Beachten Sie, dass die Feld- / Wortaufteilung in der Liste der Erweiterungen für Variablenzuweisungen im bashHandbuch weggelassen wird . Dieses Verhalten stimmt mit der POSIX-Spezifikation überein . Also, wenn du schreibst

text="$@"

Die Variable texterhält alle Positionsparameter als ein einziges Wort, entsprechend dem, was Sie geschrieben haben text="$*". Dies ist in der Tat der Grund, warum doppelte Anführungszeichen bei Variablenzuweisungen häufig nicht erforderlich sind. Beide

text=$@

und

text=$*

sind vollkommen sicher.

So,

text=$@
zenity --option="$text"

erweitert sich "$text"zu einem einzigen Wort, weshalb dies funktioniert. Beachten Sie, dass dies --option="$@"nur ein normales Argument für den Befehl zenityist und keine Zuweisung von Shell-Variablen, weshalb die Wortaufteilung hier stattfindet, jedoch nicht in text=$@.

jw013
quelle
1
+1. Dies funktioniert auch: zenity --text="$*"- wird "$*"zu einem einzigen Wort erweitert.
Glenn Jackman
+1, um mir eines beizubringen: Mann! = Dokumentation. Ich hätte nach Info Bash suchen sollen, es enthält auch den manuellen Abschnitt, auf den Sie verlinkt haben.
Manatwork
7

$@ Jeder Parameter wird in einem eigenen Wort erweitert und wird

zenity --entry --text="arg1" "arg2" "arg3" # syntactically wrong for zenity

Verwenden Sie $*stattdessen, um es in einem einzigen Wort zu erweitern

zenity --entry --text="$*"

was wird werden

zenity --entry --text="arg1 arg2 arg3" # syntactically correct for zenity
Mann bei der Arbeit
quelle
Bitte beleuchten Sie, warum die $ text-Variante aus der OP-Frage wie erwartet funktioniert
iruvar
@ChandraRavoori, du hast mich damit erwischt. Gemäß dem Handbuch "Wortaufteilung wird nicht durchgeführt, mit Ausnahme von" $ @ "" und "Wenn die Erweiterung in doppelten Anführungszeichen innerhalb eines Wortes auftritt, wird die Erweiterung des ersten Parameters mit dem Anfangsteil des ursprünglichen Wortes verbunden. und die Erweiterung des letzten Parameters wird mit dem letzten Teil des ursprünglichen Wortes verbunden. “, daher würde ich erwarten text="$@", erweitert zu werden text="arg1" "arg2" "arg3", was fehlschlagen sollte. Ist aber sicher nicht der Fall.
Manatwork
@ChandraRavoori Der Grund dafür ist, dass die Feldaufteilung bei Variablenzuweisungen nicht erfolgt. Ich erkläre es in meiner Antwort ausführlicher .
jw013
@ jw013: Aber nach dem Bash - Referenzhandbuch , "$@" tut Wort Spaltung unterzogen werden , auch in Variablenzuweisungen.
Ruakh
@ruakh Das Bash-Handbuch sagt das meines Wissens nicht aus. Haben Sie ein Angebot?
jw013