gpt4 book ai didi

shell - bourne shell 空白错综复杂

转载 作者:行者123 更新时间:2023-12-01 09:06:15 25 4
gpt4 key购买 nike

$ freebsd-version 
10.3-RELEASE-p17
$

portinstall() {
port="$1"; shift
env="$@"

#1
env "$@" printenv | grep -E '^WITH(OUT)?='
#2
env "$env" printenv | grep -E '^WITH(OUT)?='
#3
env "$*" printenv | grep -E '^WITH(OUT)?='
#4
env $@ printenv | grep -E '^WITH(OUT)?='
#5
env $* printenv | grep -E '^WITH(OUT)?='

}


portinstall foo/bar WITH='baz xyzzy' WITHOUT='quux'

只有#1 有效,它的输出:

 WITHOUT=quux
WITH=baz xyzzy

#2,#3(WITH 只是一个变量“baz xyzzy WITHOUT=quux”):

  WITH=baz xyzzy WITHOUT=quux

#4,#5

 env: xyzzy: No such file or directory

我的主要问题是为什么 #1 有效,但看似等效的 #2 却无效?

最佳答案

使用 "$@" 通常是正确的,但也许这个分析会帮助您理解原因。

您的代码大约是:

env="$@"

#1
env "$@" printenv | grep -E '^WITH(OUT)?='
#2
env "$env" printenv | grep -E '^WITH(OUT)?='
#3
env "$*" printenv | grep -E '^WITH(OUT)?='
#4
env $@ printenv | grep -E '^WITH(OUT)?='
#5
env $* printenv | grep -E '^WITH(OUT)?='

并且您正在使用参数 WITH='baz xyzzy' WITHOUT='quux' 调用脚本。是的,您有一个函数和一个备用参数作为 $1 增加了复杂性,但它们大多是无关紧要的;这是核心。

通常,$* 映射到参数中由空格分隔的单词; $@ 做同样的事情。当用双引号引起来时,它们的行为不同:"$@" 扩展为保留内部空格的参数集,而 "$*" 映射为具有内部空格的单个字符串保留空格,参数之间有一个空格。

但是,在 env="$@" 的上下文中,赋值的行为类似于 env="$*" — 您最终在多变的。为了保留单独的参数,在 Bash 中,您将使用一个数组:

env=("$@")

您可以使用以下方式打印它们:

printf '%s\n' "${env[@]}"

然而,这是一个切线。

对于 #1,您以调用 env 结束,其中包含两个有效的、保留空间的分配,printenv 适本地打印和 grep过滤器,为您提供两个变量值。这就是为什么 "$@" 通常是正确的。

对于#2 和#3,您最终会调用 env 并使用以 WITH= 开头的单个字符串(因此它分配给变量 WITH,字符串的其余部分是 baz xyzzy WITHOUT=quux,这就是您将其视为输出的原因。只有一个环境变量 — WITH — 但其值包含空格和一项任务。

使用#4 和#5,您已经运行:

env WITH=baz xyzzy WITHOUT=quux printenv

因为 xyzzy 不是一个赋值,它被当作一个命令来调用,参数是 WITHOUT=quuxprintenv (还有WITH=baz 添加到环境中),但是您的 PATH 中没有名为 xyzzy 的程序,所以 env 给您错误.您可以创建一个程序 xyzzy 来显示正在发生的事情。

使用数组env,你可以运行:

env "${env[@]}" printenv | …

你会得到与#1 相同的结果。

关于shell - bourne shell 空白错综复杂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42732066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com