有点困惑 yash shell 中的 printf 是否是内置命令

有点困惑 yash shell 中的 printf 是否是内置命令

外壳yash有一个printf内置的,根据其手册

然而,这是我在yash默认配置的 shell 中看到的:

$ command -v printf
/usr/bin/printf
$ type printf
printf: a regular built-in at /usr/bin/printf

这个 shell 中是否printf有内置的?对于许多其他所谓的内置实用程序来说,结果类似,这些实用程序也可以作为外部命令使用。

作为比较,在pdksh( kshOpenBSD 上,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

贝壳yashprintf拥有并且确实使用(和其他实用程序)的内置版本。它恰好在制定command -v和命令结果的方式上非常迂腐地符合 POSIX 标准type

正如大多数评论,POSIX 标准要求常规内置命令可用作$PATH要执行的命令的内置版本的外部命令。

这是标准中的相关文本:

命令搜索和执行

如果简单命令产生命令名称和可选参数列表,则应执行以下操作:

  1. 如果命令名称不包含任何 <slash> 字符,则应按以下顺序执行第一个成功步骤:

    • A。如果命令名称与特殊内置实用程序的名称匹配,则应调用该特殊内置实用程序。

      [...]

    • e.否则,应使用 PATH 环境变量搜索命令,如 XBD 环境变量中所述:
      • 我。如果搜索成功:
        • A。如果系统已将实用程序实现为常规内置函数或 shell 函数,则应在路径搜索中的此时调用它。
        • b.否则,shell 将在单独的实用程序环境中执行该实用程序 [...]
          [...]
      • 二.如果搜索不成功,命令将失败,退出状态为 127,并且 shell 将写入一条错误消息。
  2. 如果命令名称至少包含一个<斜杠>,[...]

这意味着 的输出command -v printf表示该printf命令曾是在搜索路径中找到,而 的输出type printf添加了该命令是常规内置命令。

由于该printf命令是在搜索路径中找到的,并且它是 shell 中的常规内置命令,yash将调用其内置版本的命令。如果printf不是在路径中找到,如果yashshell 在 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 格式 [参数 ...]
$

相关内容