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


14

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ビルトインこのシェルではありませんか?結果は、外部コマンドとしても利用可能な、他の多くの組み込みユーティリティと同様です。

比較として、pdkshkshOpenBSDでは、組み込みで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
それはビルトインです- 特別なビルトインではなく、レギュラーです。特別ビルトインと通常のビルトインの違い、または標準で義務付けられている動作(コマンド検索と実行 1.eiaを参照)について混乱している場合- 通常のビルトインのためにバイナリが存在する必要がある実行される-それについてあなたの質問をしてください。PATH
mosvy

1
@mosvyこれは私には知られていない標準の詳細でした。それを答えにしたいなら、私は幸せです。私はこの特定の詳細を知らなかったので、これを適切な答えになるように質問を更新する必要はないと思います。または、後で自分で書きます。
クサラナナンダ

回答:


14

yashシェルはていて、使用しない、内蔵されたバージョンのprintf(および他のユーティリティ)。それはたまたまcommand -vtypeコマンドとコマンドの結果を定式化する方法で、非常に教育的にPOSIXに準拠しています。

mosvyコメントとして、POSIX標準では、コマンド$PATHのビルトインバージョンを実行するために、通常のビルトインコマンドを外部コマンドとして使用できるようにする必要があります。

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

コマンドの検索と実行

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

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

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

      [...]

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

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

以来printf、コマンドサーチパスで見つかった、そしてそれは、組み込みのシェルで通常のだから、yashその組み込みコマンドのバージョンを呼び出します。場合printfしていない場合は、パスで見つかった、とyashシェルがPOSIX-LY正しいモードで実行されていた、エラーが代わりに生成されていたであろう。

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

-v

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

  • ユーティリティー、文字を含む通常の組み込みユーティリティー、および変数を使用して検出される実装定義の関数(「コマンドの検索と実行」を参照)は、絶対パス名として書き込まれます。command_names<slash>PATH

3
組み込みコマンドを実行する前に、POSIXに外部コマンドが存在する必要がある理由を誰かが知っていますか?
スタッド

@studogあなたは、おそらくこの答えや質問を参照して、別の新しい質問としてそれを尋ねることができます。
クサラナナンダ


6

Watanabeシェルには3種類のビルトインがあり、マニュアルで詳しく説明されています。すべての組み込みコマンドもそこにリストされていますが、コマンドが「特殊」または「半特殊」であるという注記がないため、何かが「通常の」組み込みコマンドであると推測する必要ありますビルトイン。通常の組み込みはマークされていません。

printfそのような「通常の」ビルトインです。ネイティブモードでは、その名前で外部コマンドが見つかったかどうかに関係なく、常に呼び出されます。

$ PATH = / usr / bin 
$ printf
printf:このコマンドにはオペランドが必要です
$ タイプprintf
printf:/ usr / bin / printfの標準ビルトイン
$
$ PATH = / 
$ printf
printf:このコマンドにはオペランドが必要です
$ タイプprintf
printf:通常の組み込み($ 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シェルは、を検索するステップの前に、通常の組み込みが常に検出されるドキュメントを作成します。Debian Almquistシェルも同様です。そして、それはこれらのシェルがすべてすることです。たとえPOSIXを有効にするオプションで呼び出されたとしてもです。PATHsh

/ bin / exec -a sh zsh -c "PATH = /;タイプprintf; printf"
printfはシェル組み込みです
zsh:printf:1:引数が不足しています
%/ bin / exec -a sh ksh93 -c "PATH = /;タイプprintf; printf"
printfはシェル組み込みです
使用法:printf [options] format [string ...]
%/ bin / exec -a sh bash --posix -c "PATH = / type printf; printf"
printfはシェル組み込みです
printf:使用法:printf [-v var]形式[引数]
%/ bin / exec -a sh dash -c "PATH = /;タイプprintf; printf"
printfはシェル組み込みです
sh:1:printf:使用法:printf形式[引数...]
% 

ただし、PD Kornシェル、Heirloom Bourneシェル、およびMirBSD Kornシェルの動作は、起動printfしていないときに実行されませんPATHprintfそもそも組み込み機能がないためです。☺

/ 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 = /;タイプprintf; printf "
printfが見つかりません
sh:printf:見つかりません
%/ bin / exec -a sh mksh -c "PATH = /;タイプprintf; printf"
printfが見つかりません
sh:printf:見つかりません
%ksh -c "type printf; printf"
printfは、/ usr / bin / printfの追跡されたエイリアスです
使用法:printf形式[引数...]
%oksh -c "type 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形式[引数...]
$

良い!確認し、私の知識にシェル固有のビットを追加していただきありがとうございます!私はすでにこのシェルが好きです。
クサラナナンダ

-1

文言を改善することができます。

シェルがposixモードの場合set --posixly-correct::

PATHに存在しない通常のビルトインの場合、次のように出力されます。

pushd: a regular built-in (not found in $PATH)

これは明確な説明です:これは組み込みですが、PATHに同じ名前の実行可能ファイルはありません。

ただし、PATHにも名前が存在する通常の組み込みの場合は、次のように出力されます。

echo: a regular built-in at /bin/echo

これは、/ bin / echoの実行可能ファイルが実行されることを意味するようです(実行されません)。からatに変更することをお勧めしalso found in PATH atます。

echo: a regular built-in also found in PATH at /bin/echo

より良い説明をするでしょう。(他の答えがそうであったように)括弧で囲むことで改善できるかもしれません。


POSIXモードでは、何の定期的な組み込みは動作しませんしない限り、それがされても、 PATHで見つかりました。

ただし、両方(POSIX)特別:

break colon continue dot eval exec exit export
readonly return set shift times trap unset

yashの準特別(POSIXに特別ではありません):

alias bg cd command false fc fg getopts jobs
kill pwd read true umask unalias wait

ビルトインは引き続き機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.