Perché --text = “$ @” passa solo la prima parola?


9

Quando eseguo il seguente script con alcuni argomenti come arg1 arg2 arg3:

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

zenity crea una finestra di dialogo di immissione con questo testo: "arg1" mentre mi aspetto "arg1 arg2 arg3"

Se uso una variabile come il seguente script, mostra tutti gli argomenti per il testo della voce.

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

Qual è la differenza tra questi script? Perché il primo sostituisce solo $@con il primo argomento?

Risposte:


16

$@si espande in parole separate (mentre si $*espande in una sola parola), come spiegato nel bashmanuale . Quindi, quando scrivi

zenity --text="$@"

si espande a

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

Tuttavia, le assegnazioni delle variabili della shell non subiscono la suddivisione delle parole. Si noti che la divisione di campi / parole viene omessa nell'elenco delle espansioni per le assegnazioni di variabili nel bashmanuale . Questo comportamento è coerente con le specifiche POSIX . Quindi, quando scrivi

text="$@"

la variabile textottiene tutti i parametri posizionali come una singola parola, equivalente a se tu avessi scritto text="$*". In effetti, questo è il motivo per cui le doppie virgolette non sono spesso necessarie nelle assegnazioni di variabili. Tutti e due

text=$@

e

text=$*

sono perfettamente sicuri.

Così,

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

si espande "$text"in una sola parola, motivo per cui funziona. Si noti che --option="$@"è solo un normale argomento per il comando zenitye non un'assegnazione di variabili shell, motivo per cui la suddivisione delle parole avviene qui ma non in text=$@.


1
+1. Questo funzionerà anche: zenity --text="$*"- si "$*"espande in una sola parola.
Glenn Jackman,

+1 per avermi insegnato una cosa: uomo! = Documentazione. Avrei dovuto cercare informazioni bash, contiene anche la sezione manuale a cui ti sei collegato.
arte

7

$@ si espande ogni parametro in una parola separata, diventando

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

Usa $*invece per espanderlo in una sola parola

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

che diventerà

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

Per favore fai luce sul perché la variante $ text dalla domanda del PO funziona come previsto
iruvar,

@ChandraRavoori, mi hai beccato con quello. Secondo il manuale "La suddivisione in parole non viene eseguita, ad eccezione di" $ @ "" e "Se l'espansione tra virgolette doppie si verifica all'interno di una parola, l'espansione del primo parametro viene unita alla parte iniziale della parola originale, e l'espansione dell'ultimo parametro è unita all'ultima parte della parola originale. ”, quindi mi aspetterei text="$@"di essere espanso text="arg1" "arg2" "arg3", che dovrebbe fallire. Ma certamente non è il caso.
arte

@ChandraRavoori Il motivo della divisione dei campi non avviene nelle assegnazioni variabili. Spiego più in dettaglio nella mia risposta .
jw013,

@ jw013: Ma secondo la Bash Reference Manual , "$@" fa subire suddivisione in parole, anche in assegnazioni di variabili.
Ruakh,

@ruakh Il manuale di Bash non lo dice per quanto ne so. Hai un preventivo?
jw013,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.