
外殼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 `指令 -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 格式 [參數 ...] $