有點困惑 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

yash貝殼printf擁有並且確實使用(和其他實用程式)的內建版本。它恰好在製定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 `指令 -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 格式 [參數 ...]
$

相關內容