Чи можу я безпечно опустити цитати в правій частині місцевого завдання?
function foo {
local myvar=${bar}
stuff()
}
Мене в основному цікавить bash, але будь-яка інформація про кутові корпуси в інших оболонках вітається.
Чи можу я безпечно опустити цитати в правій частині місцевого завдання?
function foo {
local myvar=${bar}
stuff()
}
Мене в основному цікавить bash, але будь-яка інформація про кутові корпуси в інших оболонках вітається.
Відповіді:
Котирування необхідні export foo="$var"або local foo="$var"(або readonly, typeset, declareта інші змінні оголошенні команд ) в:
dashshз NetBSD (також на основі Almquist оболонки).shЗ FreeBSD 9.2 або старше (див змін до 9.3 )yashzshз версіями до 5.1 в kshабо shемуляції (або для того, export var="$(cmd)"де zshбуло б виконано розділення слів в іншому випадку (не глобулювання)).Оскільки інакше розширення змінної буде підлягати розщепленню слів та / або генерації імен файлів, як у будь-якому аргументі будь-якої іншої команди.
І вони не потрібні:
bashksh (усі реалізації)shз FreeBSD 9.3 або більш пізньої версіїsh(з 2005 р.)zshУ zsh, split + glob ніколи не робиться при розширенні параметрів, якщо тільки не відбувається shабо kshемуляція, але роздвоєння (не glob) робиться після заміни команди. Оскільки версія 5.1, export/ localта інші команди декларації стали подвійними ключовими словами / вбудованими командами, як і в інших оболонках вище, що означає, що цитування не є необхідним, навіть в sh/ kshемуляції та навіть для заміни команд.
Існують особливі випадки, коли цитування потрібно навіть у цих оболонках, хоча так:
a="b=some value"
export "$a"
Або загалом, якщо що-небудь, що залишилося від =(включаючи =), цитується або є результатом якогось розширення (наприклад export 'foo'="$var", export foo\="$var"або export foo$((n+=1))="$var"(що $((...))також має бути цитується фактично) ...). Або іншими словами, коли аргумент exportне буде дійсним призначенням змінної, якщо він написаний без знака export.
Якщо export/ localім'я команди сам котируються (навіть в частині , як "export" a="$b", 'ex'port a="$b", \export a="$b"або навіть ""export a="$b"), лапки навколо $bпотрібні тільки в AT & T kshі mksh.
Якщо export/ localабо якась її частина є результатом деякого розширення (наприклад, у cmd=export; "$cmd" a="$b"або навіть export$(:) a="$b") або в подібних речах dryrun=; $dryrun export a="$b"), то лапки потрібні в кожній оболонці.
У випадку з > /dev/null export a="$b"котируваннями потрібні pdkshдеякі та його похідні.
Для command export a="$b", лапки необхідні в будь-який оболонці , але mkshі ksh93(з тими ж застереженнями по приводу commandі exportне є результатом якого - то розширення).
Вони не потрібні в жодній оболонці, коли пишеться:
foo=$var export foo
(цей синтаксис також сумісний з оболонкою Bourne, але в останніх версіях zsh, працює лише під час введення sh/ kshемуляції).
(зауважте, var=value local varйого не слід використовувати, оскільки поведінка різниться в оболонках).
Також зауважте, що використання exportз призначенням також означає, що статус виходу cmdв export var="$(cmd)". Зробити це так, як export var; var=$(cmd)немає цієї проблеми.
Також остерігайтеся цього особливого випадку bash:
$ bash -c 'IFS=; export a="$*"; echo "$a"' bash a b
ab
$ bash -c 'IFS=; export a=$*; echo "$a"' bash a b
a b
Моя порада буде завжди цитувати.
zshлапках будуть необхідні для local foo="$(cmd)"тому wordsplitting (але не ім'я файлу покоління) буде виконуватися для некотируваних підстановки команд (але не для некотируваних розширень параметрів), якщо KSH_TYPESETне включене, і в цьому випадку лапки НЕ потрібна. Мати сенс? Ні? Тоді завжди цитуйте все, якщо ви точно не знаєте, що робите.
Я загалом цитую будь-яке використання змінних, де можуть бути символи, такі як пробіли. Інакше у вас виникнуть такі проблеми:
#!/bin/bash
bar="hi bye"
function foo {
local myvar=${bar}
printf "%s\n" $myvar
printf "%s\n" "$myvar"
}
foo
Використання змінної у призначенні, як видається, не потребує лапок, але коли ви перейдете до її використання, як, наприклад, у printfпотрібному вам цитуванні:
printf "%s\n" "$myvar"
ПРИМІТКА. Пам'ятайте, що змінна $IFS- це те, що регулює, якими є символи роздільника.
IFS The Internal Field Separator that is used for word splitting after
expansion and to split lines into words with the read builtin command.
The default value is ``<space><tab><newline>''.
Увімкнувши налагодження в Bash, ми можемо бачити, що відбувається за кадром.
$ bash -x cmd.bash
+ bar='hi bye'
+ foo
+ local 'myvar=hi bye'
+ printf '%s\n' hi bye
hi
bye
+ printf '%s\n' 'hi bye'
hi bye
У вищесказаному ми можемо побачити, що змінна $barбула передана штрафом, $myvarале тоді, коли ми перейшли до використання, $myvarнам довелося визначити вміст, $myvarколи ми перейшли до її використання.
bashі kshв local/ typeset... Спеціальні модулі).