kjo*_*kjo 5 scripting zsh shell-script
是否有$path比以下代码段中显示的更轻松的方法来设置数组的本地版本?
foo () {
local holdpath
holdpath=($path)
local path
path=($holdpath)
if ( some_condition ) path=( $PREFIX $path )
# do stuff
}
Run Code Online (Sandbox Code Playgroud)
我特别指的是与holdpath...的歌舞
如果相反我定义
foo () {
local path=($path)
if ( some_condition ) path=( $PREFIX $path )
# do stuff
}
Run Code Online (Sandbox Code Playgroud)
...第一个赋值path触发bad pattern错误。当然,如果相反我定义
foo () {
local path
path=($path)
if ( some_condition ) path=( $PREFIX $path )
# do stuff
}
Run Code Online (Sandbox Code Playgroud)
...第一次赋值path没有区别(即可以省略而不改变结果);有或没有它,$path都会是空的。
编辑:
以下脚本测试了我目前得到的各种建议:
foo_0 () {
echo ${#path}
local PATH=$PATH
echo ${#path}
}
foo_1 () {
echo ${#path}
eval "local path; path=(${(q)path})"
echo ${#path}
}
foo_2 () {
echo ${#path}
eval "$(local -p path)"
echo ${#path}
}
for i ( 0 1 2 ) {
fn=foo_$i
echo "# $fn"
$fn
echo
}
Run Code Online (Sandbox Code Playgroud)
输出是:
# foo_0
22
22
# foo_1
22
1
# foo_2
22
22
Run Code Online (Sandbox Code Playgroud)
所以输出foo_0和foo_2至少与我试图实现的目标一致。foo_1上面给出的某些东西不起作用,但我摆脱(q)了分配给path,即
foo_1 () {
echo ${#path}
eval "local path; path=($path)"
echo ${#path}
}
Run Code Online (Sandbox Code Playgroud)
...然后输出与foo_0和 的一致foo_2。不幸的是,即使在阅读了q几次限定符的文档之后,我还是不太明白它在原始配方中应该做什么。
另外,我不明白为什么以下命令行变体foo_0与上面的不同:
% (foo_0a () { echo ${#path}; local PATH=$PATH; echo ${#path} }; foo_0a)
22
1
Run Code Online (Sandbox Code Playgroud)
FWIW,相应的命令行的变体foo_1和foo_2产生相同的结果作为其在脚本原稿:
% (foo_1a () { echo ${#path}; eval "local path; path=(${(q)path})"; echo ${#path} }; foo_1a)
22
1
% (foo_2a () { echo ${#path}; eval "$(local -p path)"; echo ${#path}; }; foo_2a)
22
22
Run Code Online (Sandbox Code Playgroud)
此外,在上述所有情况下,echo ${#path}产生1而不是22原因是局部$path变量包含单个字符串中的所有单独路径,用空格分隔。
使用标量PATH形式而不是数组path。使这些本地有效地使它们都本地化,因此:
foo() {
local PATH=$PATH
if ( some_condition ) path=( $PREFIX $path )
# do stuff
}
Run Code Online (Sandbox Code Playgroud)
(请注意,如果某些路径组件具有嵌入的:. ,则这将不起作用。)
不幸的是,不可能在一个语句中初始化本地数组参数,从而无法使用其原始值初始化本地数组参数。
对于绑定数组,您可以使用rici 的答案,在一般情况下,您可以这样做:
foo() {
eval "local array; array=(${(q)array[@]})"
...
}
Run Code Online (Sandbox Code Playgroud)
这(q)是引用数组的元素。例如,对于$PATHlike的值/foo bar:/x$y,"${(q)path[@]}"将扩展为/foo\ bar /x\$y。我们需要转义这些空格和美元字符,因为该字符串被传递给eval.
你还可以这样做:
foo() {
eval "$(local -p array)"
...
}
Run Code Online (Sandbox Code Playgroud)
它适用于任何类型的变量,但这会产生一个额外的过程。
| 归档时间: |
|
| 查看次数: |
205 次 |
| 最近记录: |