外壳yash
有一个printf
内置的,根据其手册。
然而,这是我在yash
默认配置的 shell 中看到的:
$ command -v printf
/usr/bin/printf
$ type printf
printf: a regular built-in at /usr/bin/printf
这个 shell 中是否printf
有内置的?对于许多其他所谓的内置实用程序来说,结果类似,这些实用程序也可以作为外部命令使用。
作为比较,在pdksh
( ksh
OpenBSD 上,printf
其中不是内置):
$ command -v printf
/usr/bin/printf
$ type printf
printf is /usr/bin/printf
并且在bash
(其中printf
是内置):
$ command -v printf
printf
$ type printf
printf is a shell builtin
答案1
贝壳yash
做printf
拥有并且确实使用(和其他实用程序)的内置版本。它恰好在制定command -v
和命令结果的方式上非常迂腐地符合 POSIX 标准type
。
正如大多数评论,POSIX 标准要求常规内置命令可用作$PATH
要执行的命令的内置版本的外部命令。
这是标准中的相关文本:
命令搜索和执行
如果简单命令产生命令名称和可选参数列表,则应执行以下操作:
如果命令名称不包含任何 <slash> 字符,则应按以下顺序执行第一个成功步骤:
A。如果命令名称与特殊内置实用程序的名称匹配,则应调用该特殊内置实用程序。
[...]
- e.否则,应使用 PATH 环境变量搜索命令,如 XBD 环境变量中所述:
- 我。如果搜索成功:
- A。如果系统已将实用程序实现为常规内置函数或 shell 函数,则应在路径搜索中的此时调用它。
- b.否则,shell 将在单独的实用程序环境中执行该实用程序 [...]
[...]- 二.如果搜索不成功,命令将失败,退出状态为 127,并且 shell 将写入一条错误消息。
- 如果命令名称至少包含一个<斜杠>,[...]
这意味着 的输出command -v printf
表示该printf
命令曾是在搜索路径中找到,而 的输出type printf
添加了该命令是常规内置命令。
由于该printf
命令是在搜索路径中找到的,并且它是 shell 中的常规内置命令,yash
将调用其内置版本的命令。如果printf
是不是在路径中找到,如果yash
shell 在 POSIX-ly 正确模式下运行,则会生成错误。
yash
它以自己是一个非常符合 POSIX 标准的 shell 而自豪,如果我们看一下,这也是事实POSIX 说了什么command -v
:
-v
将字符串写入标准输出,指示当前 shell 执行环境中 shell 将使用的路径名或命令(请参阅Shell执行环境),调用
command_name
,但不调用command_name
.
- 公用事业,常规内置实用程序,
command_names
包括一个<slash>
字符,以及使用该变量找到的任何实现定义的函数PATH
(如中所述命令搜索和执行),应写为绝对路径名。
答案2
Watanabe shell 具有三种内置功能,在其手册中有详细描述。所有内置命令也都列在那里,但必须从缺席任何说明该命令是“特殊”或“半特殊”内置命令。常规内置插件没有标记。
printf
就是这样一个“常规”内置的。在本机模式下是总是调用,无论是否存在使用该名称的外部命令。
$路径=/usr/bin $打印函数 printf:该命令需要一个操作数 $类型 printf printf:/usr/bin/printf 中的常规内置函数 $ $路径=/ $打印函数 printf:该命令需要一个操作数 $类型 printf printf:常规内置函数(在 $PATH 中找不到) $
但是,当posixly-correct
设置 shell 选项时,如果可以在PATH
.
$设置--posixly-正确 $ $路径=/usr/bin $打印函数 printf:该命令需要一个操作数 $ $路径=/ $打印函数 yash:没有这样的命令“printf” $
这实际上符合 Single Unix 规范的规定,并且至少从 1997 年起就已经规定了。
它与 Z shell、93 Korn shell、Bourne Again shell 和 Debian Almquist shell 不同,这些 shell 都没有实现或记录常规内置程序的此类行为。例如,Z shell 记录了常规内置命令总是成立,前搜索的步骤PATH
。 Debian Almquist shell 也是如此。这就是这些 shell 的作用,即使是sh
通过它们的打开 POSIX 选项来调用。
%/bin/exec -a sh zsh -c "PATH=/ ; 输入 printf ; printf" printf 是 shell 内置函数 zsh:printf:1:参数不足 %/bin/exec -a sh ksh93 -c "PATH=/ ; 输入 printf ; printf" printf 是 shell 内置函数 用法: printf [ 选项 ] 格式 [ 字符串 ... ] %/bin/exec -a sh bash --posix -c "PATH=/ 类型 printf ; printf" printf 是 shell 内置函数 printf:用法:printf [-v var] 格式[参数] %/bin/exec -a sh dash -c "PATH=/ ; 输入 printf ; printf" printf 是 shell 内置函数 sh: 1: printf: 用法: printf 格式 [arg ...] %
然而, PD Korn shell、Heirloom Bourne shell 和 MirBSD Korn shell 的行为是,printf
当它不在时不运行;因为他们一开始PATH
就没有内置的。 printf
☺
%/bin/exec -a sh `命令 -v ksh` -c "PATH=/ ; 输入 printf ; printf" 找不到 printf sh: printf: 未找到 %/bin/exec -a sh `command -v oksh` -c "PATH=/ ; 输入 printf ; printf" 找不到 printf sh: printf: 未找到 %/bin/exec -a sh `命令 -v jsh` -c "PATH=/ ; 输入 printf ; printf" 找不到 printf sh: printf: 未找到 %/bin/exec -a sh mksh -c "PATH=/ ; 输入 printf ; printf" 找不到 printf sh: printf: 未找到 %ksh -c“输入 printf ; printf” printf 是 /usr/bin/printf 的跟踪别名 用法: printf 格式 [参数 ...] %oksh -c "输入 printf ; printf" printf 是 /usr/bin/printf 的跟踪别名 用法: printf 格式 [参数 ...] %jsh -c“输入 printf ; printf” printf 被散列(/usr/bin/printf) 用法: printf 格式 [参数 ...] %mksh -c“输入 printf ; printf” printf 是 /usr/bin/printf 的跟踪别名 用法: printf 格式 [参数 ...] $