Answers:
引号中需要export foo="$var"
或local foo="$var"
(或readonly
,typeset
,declare
和其他变量声明命令)中:
dash
sh
的NetBSD(也是基于Almquist壳)。sh
FreeBSD的9.2或以上的(见9.3变化)yash
zsh
ksh
或在5.1之前的版本中sh
(或在export var="$(cmd)"
其中zsh
进行仿真(否则将在其中执行分词的地方(不会出现乱码)))。否则,变量扩展将像在任何其他命令的任何自变量中一样受到词拆分和/或文件名生成的影响。
并且不需要在:
bash
ksh
(所有实现)sh
的FreeBSD 9.3或更新的sh
(自2005年起)zsh
在中zsh
,除非参数in sh
或ksh
仿真,否则split + glob永远不会在参数扩展时执行,但在命令替换时会执行split(而非glob)。从5.1版开始,export
/ local
和其他声明命令已经成为双关键字 / 内置命令,就像在上面的其他Shell中一样,这意味着即使在sh
/ ksh
仿真中,甚至对于命令替换,也不需要引用。
在某些特殊情况下,即使在这些shell中也需要引用,例如:
a="b=some value"
export "$a"
或者更一般地,如果什么事的=
(包括=
)是引用或者一些扩展的结果(如export 'foo'="$var"
,export foo\="$var"
或export foo$((n+=1))="$var"
(这$((...))
也应该实际报价)...)。或者换句话说,export
如果不带编写参数,则to的参数将不是有效的变量赋值export
。
如果export
/ local
命令名称本身是引用(甚至像部分"export" a="$b"
,'ex'port a="$b"
,\export a="$b"
或甚至""export a="$b"
),各地报价$b
都需要除AT&T ksh
和mksh
。
如果export
/ local
或其中的一部分是某种扩展的结果(例如in cmd=export; "$cmd" a="$b"
或什至export$(:) a="$b"
)或诸如dryrun=; $dryrun export a="$b"
)之类的东西,则在每个shell中都需要使用引号。
在的情况下> /dev/null export a="$b"
,pdksh
以及其中的一些派生词都需要使用引号。
对于command export a="$b"
,每个shell中都需要加引号,但必须mksh
加上和ksh93
(带有相同的警告command
,但export
不是某些扩展的结果)。
编写它们时,不需要在任何shell中使用它们:
foo=$var export foo
(该语法也与Bourne Shell兼容,但在的最新版本中zsh
,仅在sh
/中有效ksh
仿真中有效)。
(注意 var=value local var
由于行为在外壳之间会有所不同不应使用)。
另请注意,export
与分配一起使用还意味着cmd
in 的退出状态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
...特殊建宏)。