Shell-Script

局部變數賦值是否需要引號?

  • December 16, 2020

我可以安全地省略本地作業右側的引號嗎?

function foo {
   local myvar=${bar}
   stuff()
}

我主要對 感興趣bash,但歡迎提供有關其他外殼中角落案例的任何資訊。

export foo="$var"在or local foo="$var"(或readonly,typesetdeclare其他變數聲明命令)中需要引號:

  • dash版本 0.3.8-15 到 0.5.10.2(參見更改)。
  • NetBSD的sh(也基於 Almquist shell)。
  • shFreeBSD 9.2 或更早的版本(請參閱9.3中的更改
  • yash
  • zshkshsh仿真中使用 5.1 之前的版本(或用於export var="$(cmd)"zsh其他情況下執行分詞的地方(不是萬用字元))。

否則,變數擴展將受到分詞和/或文件名生成的影響,就像在任何其他命令的任何參數中一樣。

並且不需要:

  • bash
  • ksh(所有實現)
  • shFreeBSD 9.3 或更新版本
  • busybox 的灰基sh(自 2005 年起)
  • zsh
  • dash0.5.11 或更新版本。

In zsh, split+glob 永遠不會在參數擴展時完成,除非 inshksh仿真,但 split(不是 glob)是在命令替換時完成的。從 5.1 版本開始,export/local和其他聲明命令已成為雙關鍵字/內置命令,就像在上面的其他 shell 中一樣,這意味著引用不是必需的,即使在sh/ kshemulation 甚至命令替換中也是如此。

在某些特殊情況下,即使在這些 shell 中也需要引用,例如:

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&Tkshmksh最新版本的dash.

如果export/local或其中的某些部分是某些擴展(例如 incmd=export; "$cmd" a="$b"或什export$(:) a="$b"至)或類似dryrun=; $dryrun export a="$b") 的結果,則除了最近版本的dash.

在 的情況下> /dev/null export a="$b",需要引號pdksh和它的一些派生詞。

對於command export a="$b", 每個 shell 都需要引號,但mksh, ksh93, recentdashbash -o posix(有同樣的警告,commandexport不是除 之外的 shell 中的某些擴展的結果dash)。

編寫時在任何 shell 中都不需要它們:

foo=$var export foo

(該語法也與 Bourne shell 兼容,但在最新版本中zsh,僅在sh/ksh仿真中有效)。

(請注意,var=value local var不應使用,因為行為因外殼而異)。

另請注意,使用exportwith 賦值也意味著cmdin的退出狀態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

我的建議是總是引用。

引用自:https://unix.stackexchange.com/questions/97560