在某些shell中(包括bash
):
IFS=: command eval 'p=($PATH)'
(使用bash
,您可以省略command
sh / POSIX仿真中的if)。但是请注意,在使用不带引号的变量时,通常还需要set -f
,而且大多数shell中都没有本地范围。
使用zsh,您可以执行以下操作:
(){ local IFS=:; p=($=PATH); }
$=PATH
是强制分词,默认情况下不进行分词(也不进行zsh
变量扩展时的globbing,因此set -f
除非在sh仿真中,否则您不需要)。
(){...}
(或function {...}
)称为匿名函数,通常用于设置本地范围。对于其他在功能上支持局部作用域的shell,您可以执行以下操作:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
要在POSIX Shell中为变量和选项实现局部作用域,还可以使用https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh中提供的功能。然后,您可以将其用作:
. /path/to/locvar.sh
var=3,2,2
call eval 'locvar IFS; locopt -f; IFS=,; set -- $var; a=$1 b=$2 c=$3'
(顺便$PATH
说一句,除非zsh
像在其他shell 中那样,否则以上述方式进行拆分是无效的,IFS是字段定界符,而不是字段分隔符)。
IFS=$'\n' a=($str)
只是两个作业,一个接一个,就像a=1 b=2
。
注释说明var=value cmd
:
在:
var=value cmd arg
shell将执行/path/to/cmd
一个新的进程和传球cmd
,并arg
在argv[]
和var=value
中envp[]
。那实际上不是变量分配,而是更多将环境变量传递给执行的命令。在Bourne或Korn外壳程序中set -k
,您甚至可以编写它cmd var=value arg
。
现在,这不适用于未执行的内建函数或函数。在Bourne Shell中,在中var=value some-builtin
,var
最终设置为,就像var=value
单独设置一样。例如,这意味着var=value echo foo
(无效)的行为根据是否echo
内置而有所不同。
POSIX和/或ksh
更改了Bourne行为,仅发生在称为特殊内建类的内建类类别中。eval
是一个特殊的内置read
函数,不是。对于非特殊内置命令,仅var=value builtin
设置var
为执行该命令,使其行为类似于运行外部命令时的行为。
该command
命令可用于删除那些特殊内置函数的特殊属性。POSIX忽略的是对于和内置程序,这意味着外壳将必须实现变量栈(即使它没有指定或作用域限制命令),因为您可以这样做:eval
.
local
typeset
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
甚至:
a=1 command eval myfunction
与myfunction
作为一个函数使用或设置$a
和潜在呼叫command eval
。
这是一个真正的俯瞰,因为ksh
(该规范主要是基于)没有实现它(和AT&T ksh
和zsh
仍然没有),但现在,除了这两个,大多数shell执行它。外壳之间的行为有所不同,例如:
a=0; a=1 command eval a=2; echo "$a"
虽然。local
在支持它的shell上使用是实现本地范围的一种更可靠的方法。
IFS=: command eval …
设置IFS
持续时间eval
,而在ksh 93u中则不设置。看到ksh是奇数不合规一出是不寻常的。