
シェルyash
にはprintf
、マニュアルによると。
yash
ただし、デフォルト設定のシェルでは次のようになります。
$ command -v printf
/usr/bin/printf
$ type printf
printf: a regular built-in at /usr/bin/printf
このシェルには組み込みユーティリティがありますprintf
か? 結果は、外部コマンドとしても使用できる、組み込みユーティリティと思われる他の多くのユーティリティでも同様です。
比較として、OpenBSDのpdksh
(では、ksh
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
の結果を作成する方法が、POSIX に厳密に準拠しているだけです。command -v
type
mosvyのコメント$PATH
POSIX 標準では、組み込みバージョンのコマンドを実行するには、通常の組み込みコマンドが外部コマンドとして使用可能であることが要求されています。
これは標準からの関連テキスト:
コマンドの検索と実行
単純なコマンドがコマンド名とオプションの引数リストを生成する場合、次のアクションが実行されます。
コマンド名に <スラッシュ> 文字が含まれていない場合、次のシーケンスの最初の成功ステップが実行されます。
a. コマンド名が特別な組み込みユーティリティの名前と一致する場合、その特別な組み込みユーティリティが呼び出されます。
[...]
- e. それ以外の場合、コマンドはXBD環境変数で説明されているようにPATH環境変数を使用して検索されます。
- 私。検索が成功した場合:
- a.システムがユーティリティを通常の組み込み関数またはシェル関数として実装している場合は、パス検索のこの時点で呼び出されます。
- b. それ以外の場合、シェルは別のユーティリティ環境でユーティリティを実行します [...]
[...]- ii. 検索が失敗した場合、コマンドは終了ステータス 127 で失敗し、シェルはエラー メッセージを書き込みます。
- コマンド名に少なくとも 1 つの <スラッシュ> が含まれている場合、[...]
これは、出力がcommand -v printf
コマンドprintf
だった検索パスで見つかりますが、 の出力には、type printf
コマンドが通常の組み込みコマンドであることがこれに追加されます。
コマンドprintf
は検索パスで見つかり、シェルの通常の組み込みコマンドなので、yash
組み込みバージョンのコマンドを呼び出す. もしそれprintf
がないパス内に見つからず、yash
シェルが POSIX に正しいモードで実行されていた場合は、代わりにエラーが生成されます。
yash
POSIX準拠のシェルであることを誇りにしており、これはPOSIXが何について言っているかcommand -v
:
-v
現在のシェル実行環境でシェルが使用するパス名またはコマンドを示す文字列を標準出力に書き出します(シェル実行環境) を呼び出すことはできます
command_name
が、 を呼び出すことはできませんcommand_name
。
- ユーティリティ、通常の組み込みユーティリティ(文字
command_names
を含む<slash>
)および変数を使用して見つかった実装定義の関数PATH
(コマンドの検索と実行)、絶対パス名として記述される。
答え2
ワタナベシェルには3種類の組み込みコマンドがあり、マニュアルに詳細が説明されています。組み込みコマンドもすべてそこに記載されていますが、それが「通常の」組み込みコマンドであるかどうかは、不在コマンドが「特殊」または「半特殊」組み込みコマンドであることを示す注釈はありません。通常の組み込みコマンドにはマークがありません。
printf
はそのような「通常の」組み込み関数の1つです。ネイティブモードではいつもその名前の外部コマンドが見つかったかどうかに関係なく、呼び出されます。
$PATH=/usr/bin $プリント printf: このコマンドにはオペランドが必要です $printfと入力する printf: /usr/bin/printf の通常の組み込み関数 $ $パス=/ $プリント printf: このコマンドにはオペランドが必要です $printfと入力する printf: 通常の組み込み関数 ($PATH には存在しません) $
ただし、posixly-correct
シェル オプションが設定されている場合は、外部コマンドが で見つかる場合にのみ組み込みになりますPATH
。
$--posixly-correct を設定する $ $PATH=/usr/bin $プリント printf: このコマンドにはオペランドが必要です $ $パス=/ $プリント yash: そのようなコマンド `printf' はありません $
これは実際には Single Unix Specifiation の内容に準拠しており、少なくとも 1997 年以降はそう言われています。
これは、Zシェル、93 Kornシェル、Bourne Againシェル、Debian Almquistシェルとは異なります。これらのシェルはいずれも、通常の組み込み関数に対してこのような動作を実装または文書化していません。たとえば、Zシェルでは、通常の組み込み関数はいつも見つかった、前にを検索するステップPATH
です。Debian Almquist シェルも同様です。そして、これらのシェルはすべて、sh
POSIX をオンにするオプションで呼び出された場合でも、これを実行します。
%/bin/exec -a sh zsh -c "PATH=/ ; type printf ; printf" printfはシェルの組み込み関数です zsh:printf:1: 引数が足りません %/bin/exec -a sh ksh93 -c "PATH=/ ; タイプ printf ; printf" printfはシェルの組み込み関数です 使用法: printf [ オプション ] 形式 [ 文字列 ...] %/bin/exec -a sh bash --posix -c "PATH=/ type printf ; printf" printfはシェルの組み込み関数です printf: 使用法: printf [-v var] フォーマット [引数] %/bin/exec -a sh dash -c "PATH=/ ; type printf ; printf" printfはシェルの組み込み関数です sh: 1: printf: 使用法: printf フォーマット [arg ...] %
ただし、PD Korn シェル、Heirloom Bourne シェル、および MirBSD Korn シェルでは、最初から が組み込まれていないためprintf
、オンになっていないときに実行されないという動作になります。☺PATH
printf
%/bin/exec -a sh `command -v ksh` -c "PATH=/ ; type printf ; printf" printf が見つかりません sh: printf: 見つかりません %/bin/exec -a sh `command -v oksh` -c "PATH=/ ; type printf ; printf" printf が見つかりません sh: printf: 見つかりません %/bin/exec -a sh `command -v jsh` -c "PATH=/ ; type printf ; printf" printf が見つかりません sh: printf: 見つかりません %/bin/exec -a sh mksh -c "PATH=/ ; type printf ; printf" printf が見つかりません sh: printf: 見つかりません %ksh -c "type printf ; printf" printfは/usr/bin/printfの追跡されたエイリアスです 使用法: printf 形式 [引数 ...] %oksh -c "printf と入力; printf" printfは/usr/bin/printfの追跡されたエイリアスです 使用法: printf 形式 [引数 ...] %jsh -c "type printf ; printf" printf はハッシュ化されます (/usr/bin/printf) 使用法: printf 形式 [引数 ...] %mksh -c "type printf ; printf" printfは/usr/bin/printfの追跡されたエイリアスです 使用法: printf 形式 [引数 ...] $