web-dev-qa-db-ja.com

yashシェルのprintfが組み込みコマンドであるかどうかについて少し混乱しました

yashシェルにはprintfが組み込まれています そのマニュアルによると

ただし、これは、デフォルトの構成でyashシェルに表示されるものです。

kk@eeyore ~ $ command -v printf
/usr/bin/printf
kk@eeyore ~ $ type printf
printf: a regular built-in at /usr/bin/printf

printfはこのシェルに組み込まれていますか?結果は、外部コマンドとしても利用可能な他の多くの組み込みユーティリティと同様です。

比較として、pdksh(OpenBSDでは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
14
Kusalananda

yashシェルdoesには、組み込みバージョンのprintf(およびその他のユーティリティ)があり、実際に使用しています。 command -vおよびtypeコマンドの結果を公式化する方法が、非常に見た目上はPOSIXに準拠しているだけです。

mosvyコメント として、POSIX標準では、実行されるコマンドの組み込みバージョンの通常の組み込みコマンドを$PATHの外部コマンドとして使用できる必要があります。 。

これは 標準からの関連テキストです

コマンドの検索と実行

単純なコマンドの結果、コマンド名とオプションの引数リストが表示される場合、次のアクションが実行されます。

  1. コマンド名に<slash>文字が含まれていない場合、次のシーケンスの最初の成功したステップが発生します。

    • a。コマンド名が特別な組み込みユーティリティの名前と一致する場合、その特別な組み込みユーティリティが呼び出されます。

      [...]

    • e。それ以外の場合は、XBD環境変数で説明されているように、PATH環境変数を使用してコマンドが検索されます。
      • 私。 検索が成功した場合:
        • a。 システムがユーティリティを通常の組み込み関数またはシェル関数として実装している場合、パス検索のこの時点で呼び出されます。
        • b。それ以外の場合、シェルは別のユーティリティ環境でユーティリティを実行します[...]
          [...]
      • ii。検索が失敗した場合、コマンドは127の終了ステータスで失敗し、シェルはエラーメッセージを書き込みます。
  2. コマンド名に少なくとも1つの<slash>が含まれている場合、[...]

これは、command -v printfの出力がprintfコマンドwasが検索パスで見つかったことを示しているのに対し、type printfの出力は、コマンドに通常の組み込みです。

printfコマンドが検索パスで見つかったため、シェルの通常の組み込みコマンドであるため、-yashはコマンドの組み込みバージョンを呼び出します =。 printfnotである場合、およびyashシェルがPOSIXの正しいモードで実行されている場合は、代わりにエラーが生成されます。

yashは、非常にPOSIX準拠のシェルであることを誇りにしており、 POSIXがcommand -v について言っていることを見ると、これも当てはまります。

-v

現在のシェル実行環境(シェル実行環境を参照)でシェルが使用するパス名またはコマンドを示す文字列を標準出力に書き込み、command_nameを呼び出しますが、 command_nameを呼び出さないでください。

  • ユーティリティ、通常の組み込みユーティリティcommand_names<slash>文字を含む、および使用して検出される実装定義の関数PATH変数(コマンドの検索と実行で説明)、は絶対パス名として記述する必要があります。
14
Kusalananda

Watanabe Shellには3種類のビルトインがあり、詳細はマニュアルに記載されています。すべての組み込みコマンドもそこにリストされていますが、何かがabsenceから「通常の」組み込みコマンドであると推測する必要がありますコマンドは「特別な」または「準特別な」組み込みコマンドであるという注記。通常のビルトインはマークされていません。

printfは、そのような「通常の」組み込みの1つです。ネイティブモードでは、その名前で検出された外部コマンドがあるかどうかに関係なく、常に呼び出されます

 $ PATH =/usr/bin 
 $ printf 
 printf:このコマンドにはオペランドが必要です
 $ type printf 
 printf:/usr/bin/printf
$
$に組み込まれた通常の$ PATH = / = 
 $ printf 
 printf:このコマンドにはオペランドが必要です
 $ type printf 
 printf:a通常の組み込み($ PATHにはありません)
 $ 

しかし、posixly-correctシェルオプションが設定されています。外部コマンドがPATHにある場合、それは組み込みコマンドです。

 $ set --posixly-correct 
 $ 
 $ PATH =/usr/bin 
 $ printf 
 printf:このコマンドにはオペランドが必要です
 $ 
 $ PATH = / 
 $- printf 
 yash:そのようなコマンドはありません `printf '
 $ 

これは、実際にはSingle Unix Specifiationの発言に準拠しており、少なくとも1997年以降は発言しています。

これは、Zシェル、93 Kornシェル、Bourne Againシェル、およびDebian Almquistシェルとは異なります。これらのいずれも、通常の組み込みの動作を実装または文書化していません。 Zシェル、たとえば、通常の組み込みが常に見つかったドキュメント、beforePATHを検索するステップ。 Debian Almquist Shellも同様です。そして、それは、POSIXオプションをオンにしてshとして呼び出された場合でも、これらのシェルがすべて行うことです。

/ bin/exec -a sh zsh -c "PATH = /; type printf; printf" 
 printf is a shell builtin 
 zsh: printf:1:引数が足りません
%/ bin/exec -a sh ksh93 -c "PATH = /; type printf; printf" 
 printfは組み込みのシェルです
使用方法:printf [オプション]形式[文字列...] 
%/ bin/exec -a sh bash --posix -c "PATH =/type printf; printf" 
 printfはシェルに組み込まれています
 printf:使用法:printf [-v var] format [arguments] 
%/ bin/exec -a sh dash -c "PATH = /; type printf; printf" 
 printfは組み込みシェルです
 sh:1:printf:使用法:printf format [arg ...] 
%

ただし、printfがない場合にPATHを実行しないのは、PD Korn Shell、Heirloom Bourne Shell、およびMirBSD Korn Shellの動作です。 ;そもそもprintfが組み込まれていないためです。

/ bin/exec -a sh `command -v ksh` -c" PATH = /; type printf; printf " 
 printf not found 
 sh:printf:not found 
%/ bin/exec -a sh `command -v oksh` -c" PATH = /; type printf; printf " 
 printf not found 
 sh:printf:not found 
%/ bin/exec -a sh `command -v jsh` -c" PATH = /; type printf; printf " 
 printf not found 
 sh:printf:not found 
%/ bin/exec -a sh mksh -c "PATH = /; type printf; printf " 
 printf not found 
 sh:printf:not found 
%ksh -c" type printf; printf " 
 printfは/usr/bin/printf
の追跡されたエイリアスです。使用方法:printf形式[引数...] 
%oksh -c "type printf; printf" 
 printfは、/ usr/bin/printf 
の追跡されたエイリアスです。使用方法:printf format [arguments ...] 
%jsh -c "type printf; printf" 
 printfはハッシュされます(/usr/bin/printf)
使用法:printf形式[引数...] 
%mksh -c "type printf ; printf " 
 printfは/usr/bin/printf
の追跡されたエイリアスです:使用法:printf形式[引数...] 
 $ 
6
JdeBP