Чому --text = "$ @" передає лише перше слово?


9

Коли я запускаю такий сценарій з такими аргументами, як arg1 arg2 arg3:

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

zenity створює діалог вступу з цим текстом: "arg1", тоді як я очікую "arg1 arg2 arg3"

Якщо я використовую змінну, як у наведеному нижче сценарії, вона показує всі аргументи для тексту введення.

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

Яка різниця між цими сценаріями? Чому перший замінює $@лише перший аргумент?

Відповіді:


16

$@розширюється на окремі слова (тоді як $*розширюється на одне слово), як пояснено в bashпосібнику . Таким чином, коли пишеш

zenity --text="$@"

вона розширюється до

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

Однак призначення змінних оболонок не зазнає розбиття слів. Зауважте, що розділення на поле / слово пропущено у списку розширень для присвоєння змінних у bashпосібнику . Така поведінка відповідає специфікації POSIX . Отже, коли пишеш

text="$@"

змінна textотримує всі позиційні параметри як одне слово, еквівалентне, якби ви написали text="$*". Дійсно, це є причиною того, що подвійні лапки часто не потрібні в змінних призначеннях. І те й інше

text=$@

і

text=$*

абсолютно безпечні.

Тому,

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

розширюється "$text"до одного слова, саме тому це працює. Зауважте, що --option="$@"це просто звичайний аргумент команди zenity, а не призначення змінної оболонки, тому розбиття слів відбувається тут, але не в text=$@.


1
+1. Це також спрацює: zenity --text="$*"- "$*"розширюється на одне слово.
glenn jackman

+1 для навчання мене одному: людина! = Документація. Я повинен був шукати інформаційний баш, він також містить розділ посібника, з яким ви пов’язані.
манатура

7

$@ розширюйте кожен параметр окремим словом, стаючи

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

Використовуйте $*замість цього, щоб розгорнути його одним словом

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

що стане

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

Будь ласка, пролийте світло на те, чому варіант тексту $ з питання ОП працює так, як очікувалося
iruvar

@ChandraRavoori, ти мене з цим зловив. Згідно з посібником "Розбиття слів не виконується, за винятком" $ @ "" та "Якщо подвійне цитування розширення відбувається в межах слова, розширення першого параметра з'єднується з початковою частиною початкового слова, і розширення останнього параметра разом з останньою частиною вихідного слова. », так що я б очікувати , text="$@"щоб бути розширений text="arg1" "arg2" "arg3", що має зазнати невдачі. Але точно це не так.
манатура

@ChandraRavoori Причина полягає в тому, що розділення поля не відбувається в змінних призначеннях. Я детальніше пояснюю у своїй відповіді .
jw013

@ jw013: Але відповідно до Довідкового посібника Баша , "$@" воно зазнає розщеплення слів, навіть у змінних призначеннях.
ruakh

@ruakh Посібник з bash не говорить про це, наскільки я знаю. У вас є цитата?
jw013
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.