rah*_*hmu 48 shell-script quoting assignment
我可以安全地省略本地作业右侧的引号吗?
function foo {
local myvar=${bar}
stuff()
}
Run Code Online (Sandbox Code Playgroud)
我主要对 感兴趣bash,但欢迎提供有关其他 shell 中的边角案例的任何信息。
Sté*_*las 53
引号中需要export foo="$var"或local foo="$var"(或readonly,typeset,declare和其他变量声明命令)中:
dash版本 0.3.8-15 到 0.5.10.2(见变化)。sh的NetBSD(也是基于Almquist壳)。shFreeBSD的9.2或以上的(见9.3变化)yashzsh使用 5.1 之前的版本ksh或sh仿真(或export var="$(cmd)"在其他zsh情况下执行分词(不是通配))。否则,变量扩展将受到分词和/或文件名生成的影响,就像任何其他命令的任何参数一样。
并且不需要:
bashksh (所有实现)sh的FreeBSD 9.3或更新的sh(自 2005 年起)zshdash 0.5.11 或更新版本。在 中zsh,split+glob 永远不会在参数扩展时完成,除非 insh或kshemulation,但 split(不是 glob)在命令替换时完成。从 5.1 版开始,export/local和其他声明命令已成为双关键字/内置命令,就像上面的其他 shell 一样,这意味着不需要引用,即使在sh/ksh仿真中甚至命令替换也是如此。
在某些特殊情况下,即使在这些 shell 中也需要引用,例如:
a="b=some value"
export "$a"
Run Code Online (Sandbox Code Playgroud)
或者更一般地说,如果=(包括=) 的任何剩余部分被引用或某些扩展的结果(例如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以及最新版本dash。
如果export/local或其中的某些部分是某些扩展(例如 incmd=export; "$cmd" a="$b"或 even export$(:) a="$b")或类似dryrun=; $dryrun export a="$b")的结果,则需要引号,但dash.
在 的情况下> /dev/null export a="$b",需要在pdksh和它的一些衍生物中使用引号。
对于command export a="$b",每个 shell 中都需要引号,但是mksh、ksh93、最近dash和bash -o posix(具有相同的警告,command而export不是除 之外的其他 shell 中的某些扩展的结果dash)。
编写时在任何 shell 中都不需要它们:
foo=$var export foo
Run Code Online (Sandbox Code Playgroud)
(该语法也正在与Bourne外壳,但在最新版本的兼容zsh,只有工作时sh/ksh模拟)。
(请注意,var=value local var不应使用,因为行为因壳而异)。
另请注意,export与赋值一起使用也意味着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
Run Code Online (Sandbox Code Playgroud)
我的建议是总是引用。
| 归档时间: |
|
| 查看次数: |
9294 次 |
| 最近记录: |