`set-o posix`在WSL2 Ubuntu 20.04上的Bash 5.0.17中不工作

`set-o posix`在WSL2 Ubuntu 20.04上的Bash 5.0.17中不工作,bash,set,posix,Bash,Set,Posix,正如标题中提到的,set-oposix选项在GNU/LinuxBash5.0.17中似乎不起作用(我不确定它是否与WSL2Ubuntu20.04或其他任何东西有特别的关系,但注意到它是否在其他机器上起作用) 我可以打开和关闭它: $set-o | grep posix posix关闭 $set-o posix $set-o| grep posix posix on $set-o posix $set-o| grep posix posix关闭 $set-o posix $set-o| grep

正如标题中提到的,
set-oposix
选项在GNU/LinuxBash5.0.17中似乎不起作用(我不确定它是否与WSL2Ubuntu20.04或其他任何东西有特别的关系,但注意到它是否在其他机器上起作用)

我可以打开和关闭它:

$set-o | grep posix
posix关闭
$set-o posix
$set-o| grep posix
posix on
$set-o posix
$set-o| grep posix
posix关闭
$set-o posix
$set-o| grep posix
posix on
但是,例如,当打开时,我可以执行以下操作

$set-o posix
$set-o| grep posix
posix on
$type光盘
cd是一个内置的外壳
$cd/
$ls
bin dev home lib lib64丢失+找到mnt进程运行快照系统usr
boot etc init lib32 libx32 media opt root sbin srv tmp var
$cd(){:;}
$type光盘
cd是一个函数
cd()
{
:
}
$cd~
$ls
bin dev home lib lib64丢失+找到mnt进程运行快照系统usr
boot etc init lib32 libx32 media opt root sbin srv tmp var
$unset-f cd
$cd~
$ls
桌面文档下载音乐图片公共模板视频
我能够覆盖所有特殊内置项(包括
内置项
类型
!)。另外,我不是root,只是在我的用户帐户中。有人知道我做错了什么吗

更新:

@肖恩、@oguzismail和@Dan都给出了下面的正确答案:
cd
是一种常规的内置设备。我想补充一些说明,因为我认为这对像我这样的学习者很重要:

@oguzismail正确地指出了说明
cd
是一个常规内置的:

因此,您可以编写一个名为cd的函数,shell将 首先找到你的函数,因为cd是一个常规的内置函数

  • 第7.9节(Kindle版261页)
我的困惑来自总结中的陈述:

内置命令的存在可能是因为它们更改了shell的 内部状态,并且必须是内置的(如cd),或者是为了提高效率 (例如测试)

  • (Kindle版第264页第7节摘要)
这里,
cd
是一个内置的,但正如作者之前所说,它是一个常规的内置的。它必须是内置于shell中的命令,因为该命令会更改shell的内部状态(即,它会更改shell的当前/当前工作目录),但它可以是常规或特殊内置的。正如@Dan提到的,定义它为一个常规的内置函数。(至少出于一个原因,的第7.9节显示这样做允许程序员自定义其行为。)


不过要小心!(NB=Nota Bene):如果您选择使用用户定义的函数覆盖
cd
,请在要实际更改目录的函数定义中使用
命令cd
。函数
命令
跳过按POSIX定义的搜索顺序在$PATH上查找函数,搜索顺序为
特殊内置-->函数-->常规内置-->外部命令。否则,如果在用户定义的函数
cd
中使用
cd
,则很可能会导致无限递归循环。(也包括这一点。)

这里的关键是
bash
认为一个特殊的内置项是什么。我必须深入研究才能找到一份清单:

/*Posix.2所谓的“特殊”内置*/
字符*特殊内置字符[]=
{
“:”、“、”源“、”中断“、”继续“、”评估“、”执行“、”退出“,
“导出”、“只读”、“返回”、“设置”、“移位”、“次数”、“陷阱”、“取消设置”,
(char*)空
};
他们也被视为是不同于

事实上

$bash--posix
bash-4.4$break(){:;}
bash:'break':是一个特殊的内置项
bash-4.4$类型中断
break是一种特殊的内置外壳
bash-4.4$类型cd
cd是一个内置的外壳

请注意
break
cd
type
输出不同,因为后者不在该列表中。

设置-o posix
工作正常:

  $ set -o posix
  $ set () { :; }
bash: `set': is a special builtin
cd
不是特殊的内置光盘,也不是
内置光盘
类型

posix规范中有“特殊内置”列表


“特殊内置”有别于shell可以或不可以作为内置实现的任何其他命令。

行为的哪一部分是意外的?@choroba根据Bash文档,在POSIX模式下,您不应该能够创建与特殊内置相同名称的函数(请参阅,编号15和16).这太奇怪了,因为关于shell脚本主题的每本书都指出,
cd
必须是一个特殊的内置文件,因为你不能从外部位置使用库更改目录。也就是说,O'Reilly的经典Shell脚本和Addison Wesley的Unix、Linux和OS X中的Shell编程,更不用说大量的在线资源了。@A.Hendry我终于找到了POSIX定义特殊功能的地方:(与常规的内置实用程序相反)这是WSL2的东西,还是它通常适用于Bash?我的另一位同事说,在使用
set-oposix
之后,他们无法在用户函数中重新定义
cd
。我还注意到您使用了versio。在你的例子中是4.4,但我使用的是5.0.17版。你能确认它在版本5中有效吗?这个问题是否与WSL有关?@A.Hendry这是一个bash事件。@oguzismail噢,我的天哪,掌心,你完全正确。真尴尬。我甚至在另一篇文章中提到了这一点!是的,你说得对。关于
cd
,我犯了一个愚蠢的错误。它是一个常规内置的,而不是一个特殊的。谢谢你的提醒!