正如标题中所提到的,set -o posix
选项似乎在GNU/Linux bash 5.0.17中不起作用(我不确定它是否与WSL2 Ubuntu 20.04或任何东西有特别的关系,但请注意,以防它在他们的机器上为其他人工作(。
我可以打开和关闭:
$ set -o |grep posix
posix off
$ set -o posix
$ set -o |grep posix
posix on
$ set -o posix
$ set -o |grep posix
posix off
$ set -o posix
$ set -o |grep posix
posix on
但是,例如,当打开时,我可以进行以下
$ set -o posix
$ set -o |grep posix
posix on
$ type cd
cd is a shell builtin
$ cd /
$ ls
bin dev home lib lib64 lost+found mnt proc run snap sys usr
boot etc init lib32 libx32 media opt root sbin srv tmp var
$ cd() { :; }
$ type cd
cd is a function
cd ()
{
:
}
$ cd ~
$ ls
bin dev home lib lib64 lost+found mnt proc run snap sys usr
boot etc init lib32 libx32 media opt root sbin srv tmp var
$ unset -f cd
$ cd ~
$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
我可以覆盖所有特殊的内置程序(包括builtin
和type
!(。此外,我不是root用户,只是在我的用户帐户中。有人知道我做错了什么吗?
更新:
@Shawn、@oguzismail和@Dan都给出了以下正确答案:cd
是常规内置。我想补充一些澄清,因为我认为这对像我这样的学习者来说很重要:
@oguzismail正确地指向了经典Shell脚本的一节,该节解释了cd
是一个常规的内置:
因此,您可以编写一个名为cd的函数,shell将首先找到你的功能,因为cd是一个常规的内置
- 第7.9节(Kindle版第261页(
我的困惑来自摘要中的声明:
内置命令的存在要么是因为它们更改了shell的内部状态并且必须是内置的(如cd(,或者为了提高效率(如测试(。
- (Kindle版第264页第7节摘要(
这里,cd
是一个内建,但正如作者之前所说,它是一个正则内建。它必须是内置在shell中的命令,因为该命令会更改shell的内部状态(即更改shell的当前/当前工作目录(,但它可以是常规或特殊内置。正如@Dan所提到的,POSIX IEEE Std 1003.1-2017标准第2.14节将其定义为常规内置。(至少有一个原因,经典Shell脚本的7.9节表明,这样做允许程序员自定义其行为。(
请注意!(NB=Nota Bene(:如果您选择用用户定义的函数覆盖cd
,请在要实际更改目录的函数定义中使用command cd
。函数command
跳过在POSIX定义的special built-ins --> functions --> regular built-ins --> external commands on $PATH
的搜索顺序中查找函数。否则,如果在用户定义的函数cd
中使用cd
,则很可能会出现无限递归循环。(经典Shell脚本也涵盖了这一点。(
这里的关键是bash
认为特殊内置是什么
/* The Posix.2 so-called `special' builtins. */
char *special_builtins[] =
{
":", ".", "source", "break", "continue", "eval", "exec", "exit",
"export", "readonly", "return", "set", "shift", "times", "trap", "unset",
(char *)NULL
};
在POSIX文档中,它们也被描述为不同于常规内置程序。
事实上。。。
$ bash --posix
bash-4.4$ break() { :; }
bash: `break': is a special builtin
bash-4.4$ type break
break is a special shell builtin
bash-4.4$ type cd
cd is a shell builtin
请注意break
和cd
的type
输出不同,因为后者不在该列表中。
set -o posix
工作良好:
$ set -o posix
$ set () { :; }
bash: `set': is a special builtin
cd
不是内置的特殊,builtin
或type
也不是。
";特殊内置"在posix规范中有明确定义。
A";特殊内置";不同于shell作为内置命令实现或不实现的任何其他命令。