文字列内の Bash 組み込みの「time」は実行されません

文字列内の Bash 組み込みの「time」は実行されません
$ cmd='time sleep 2'
$ $cmd
bash: time: command not found

ここで何が起こっているのでしょうか? これはシェルの組み込み関数が機能していないという問題ではありません。これは機能します:

$ cmd2='echo wef'
$ $cmd2
wef

何か案は?

編集: 違いを見つけました:

$ type time
time is a shell keyword

対:

$ type echo
echo is a shell builtin

それで、今の疑問は、なぜ組み込み関数は文字列で機能するのに、キーワードは機能しないのか、ということです。

答え1

timeとしてGNUバッシュキーワードが受け入れられる場所は非常に限定されています。たとえば、コマンド パイプライン構造の構文を参照してください。

パイプラインの形式は [time [-p]] [!] command1 [| command2 ...]

これにより、拡張の外側のキーワードの位置がハードコードされます(コマンドNパラメータと変数が展開される場所になります)。実際、セマンティクスはコマンドではなくパイプライン全体に適用されるため、これがキーワードにする必要がある理由であると考えられます。

シェルが組み込まれていますtimes(POSIXでは特別な組み込み) の場合、最初の単語は実行可能ファイルまたはシェル組み込みファイルである可能性があるため、この展開は機能します。

あるいはGNU コアユーティリティ 実行可能ファイルが含まれています/bin/time

実際にはtimeそうではない予約語POSIX シェル(bashでは認識されますが、POSIX モードとにかく(-明白でない理由で a が続く場合を除きます)。

式の中でevalキーワードは次のように認識されますバッシュなので、これを使用して、時間プロファイリングでコマンドを動的に強化することができます。(ただし、その一方で、追加の引用符処理が必要になります)

答え2

リアルタイム コマンドを取得するには、cmd='time sleep 2' を使用する代わりに、cmd='/usr/bin/time sleep 2' として使用してみてください。

man time では次の内容を読むことができます。

bash シェルのユーザーは、シェルの組み込みバージョンではなく、外部の time コマンドを実行するために明示的なパスを使用する必要があります。time が /usr/bin にインストールされているシステムでは、最初の例は /usr/bin/time wc /etc/hosts になります。

関連情報