gpt4 book ai didi

linux - 为什么在双引号内指定部分路径时 posh 无法执行路径名扩展?

转载 作者:IT王子 更新时间:2023-10-29 00:01:58 27 4
gpt4 key购买 nike

考虑以下简单的 shell 脚本:

rm -rf bar \"bar\"
mkdir -p bar
touch bar/baz
echo "bar"/*

我用 bash、ksh、zsh 和 dash 得到了预期的输出,但我没有得到它与豪华:

susam@debian:~$ bash foo.sh
bar/baz
susam@debian:~$ ksh foo.sh
bar/baz
susam@debian:~$ zsh foo.sh
bar/baz
susam@debian:~$ dash foo.sh
bar/baz
susam@debian:~$ posh foo.sh
bar/*

我想了解 posh 的行为是否符合 POSIX 标准,或者它是否是错误。

POSIX 文档中的相关部分似乎是“2.6 Word Expansion”:

他们都提到路径名扩展发生在引用删除之前。

  1. Pathname expansion (see Pathname Expansion) shall be performed, unless set -f is in effect.
  2. Quote removal (see Quote Removal) shall always be performed last.

考虑到这一点,豪华行为看起来是正确的,因为 "bar"/* 在引号删除之前与上面的任何路径都不匹配,因此不会发生路径扩展。

所以这让我怀疑如果有一个字面上名为 "bar" 的目录,即引号是目录名称的一部分,那么 posh 会匹配它。但以下更改后的脚本表明这不是真的。

rm -rf bar \"bar\"
mkdir -p \"bar\"
touch \"bar\"/baz
echo "bar"/*

这是输出:

susam@debian1:~$ bash foo2.sh 
bar/*
susam@debian1:~$ ksh foo2.sh
bar/*
susam@debian1:~$ zsh foo2.sh
foo2.sh:3: no matches found: bar/*
susam@debian1:~$ dash foo2.sh
bar/*
susam@debian1:~$ posh foo2.sh
bar/*

因此 posh 中的模式 "bar"/* 既不匹配路径 bar/baz 也不匹配路径 "bar"/baz。那匹配什么呢?豪华行为是错误还是功能?

以下是版本详细信息,以防对您有所帮助:

susam@debian:~$ cat /etc/debian_version 
8.3
susam@debian:~$ dpkg -l bash ksh zsh dash posh
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-===========================-==================-==================-============================================================
ii bash 4.3-11+b1 amd64 GNU Bourne Again SHell
ii dash 0.5.7-4+b1 amd64 POSIX-compliant shell
ii ksh 93u+20120801-1 amd64 Real, AT&T version of the Korn shell
ii posh 0.12.3 amd64 Policy-compliant Ordinary SHell
ii zsh 5.0.7-5 amd64 shell with lots of features

最佳答案

这是 posh 中的错误 -- 请参阅错误 #636601 .从 posh 版本 0.12.6 开始,它仍然是开放的。

附于discussion在那个错误中你会发现一个 patch .应用它时,posh 的行为类似于 bash(因此在您的第一个示例中,echo "bar"/* 给出 bar/baz)。

此外,bash(和 patched posh)的行为确实符合 POSIX。标准说

  1. Quote removal (see Quote Removal) shall always be performed last.

这意味着字面意思,作为一个纯句法操作,用于在最后一步中删除保护引号。正如 hek2mgl 所指出的,引号的语义 含义仍适用于前面的步骤。 (否则,例如 "*" 这样的引号根本不会有任何效果。)

所以转念一想,这个结论是不正确的:

Considering this, the posh behaviour looks right because "bar"/* does not literally match any path above before the quote removal, so path expansion does not occur.

关于linux - 为什么在双引号内指定部分路径时 posh 无法执行路径名扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37227859/

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