bashにシェル組み込みではなく外部の `time`コマンドを使用させる


27

shellキーワードの代わりにbashにデフォルトで時間バイナリ(/ usr / bin / time)を使用させるにはどうすればよいですか?

which time戻り/usr/bin/time
type time値戻り値time is a shell keyword
Running timeは、明らかにshellキーワードを実行しています。

$ time

real    0m0.000s
user    0m0.000s
sys     0m0.000s
$ /usr/bin/time
Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]
   [--portability] [--format=format] [--output=file] [--version]
   [--quiet] [--help] command [arg...]

enable -n time 返す bash: enable: time: not a shell builtin

回答:


30

commandシェルビルトインを使用して、通常のルックアッププロセスをバイパスし、他の可能性(シェルビルトイン、エイリアスなど)に関係なく、指定されたコマンドを外部コマンドとして実行できます。これは、多くの場合、おそらくより一般的に速記を使用したものの、システム間で移植する必要があるスクリプトで行われます\(のように\rmではなく、command rmまたはrm特に後者は何かのように知られていないにエイリアスすることができるように、rm -i)。

$ time

real    0m0.000s
user    0m0.000s
sys 0m0.000s
$ command time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]
$ 

これは、次のようにエイリアスとともに使用できます。

$ alias time='command time'
$ time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]
$ 

たとえば、これの利点はalias time=/usr/bin/timetimeバイナリへのフルパスを指定するのではなく、通常のパス検索メカニズムにフォールバックすることです。

aliasコマンド自体は、例えば〜/ .bashrcに入るか/etc/bash.bashrc(後者は、システム上のすべてのユーザーに対してグローバルである)ことができます。

反対の場合(エイリアスが定義されている場合にシェル組み込みの使用を強制する)、のようなものを使用builtin timeします。これは通常の検索プロセスを再びオーバーライドし、名前付きシェル組み込みを実行します。bashのmanページでは、これは多くの場合、組み込みcd機能をcd使用cdして本物を実行するという名前の関数でカスタム機能を提供するために使用されると述べています。


コマンドを使用して、特定のコマンドがどこから来ているのかを問い合わせることもできtype -a <cmd>ます。
slm

12
commandビルトインをバイパスしません(zsh他のシェルをエミュレートしない場合を除く)。機能をバイパスし、それがその存在の主な理由です。その第二の役割は削除することです特別なのでは特殊な組み込みコマンド。エイリアスとキーワードは最初の位置でしか展開されないためにのみバイパスさzshれます(たとえば、グローバルエイリアスはバイパスされません)。timebashビルトインはありません。timeはキーワードなので、たとえばを実行できますtime { foo; bar; }
ステファンシャゼル

1
@StephaneChazelasぜひ、それを回答に編集して、より正確な説明を提供してください。command例示されているように、この特定のケースで機能しますが、正解は半正解よりも優れていることは明らかです。
CVn

1
あなたの答えの最後の部分は間違っています。timeは組み込みのシェルではなく、シェルのキーワードです。builtin time動作しません。
テレサジュニア

コマンドと同様に、引用するだけです'time' echo test
。– mxmlnkn

9

bashにはサイドパスキーワードへのショートカットがあり、パスを指定したり、次のような別の組み込みコマンドを使用したりする必要はありませんcommand。バックスラッシュでエスケープします。

=^_^= izkata@Izein:~$ time

real    0m0.000s
user    0m0.000s
sys     0m0.000s
=^_^= izkata@Izein:~$ \time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]

個人的には、これはより読みやすく安全だと思います。

=^_^= izkata@Izein:~$ alias command=echo
=^_^= izkata@Izein:~$ command time
time

8
注引用または落札何のいずれかの形式ことはないトークンはtime:行いますti\me'time'ti""meti${-##*}me${-+time}...任意のシェルキーワードに適用されます。
ステファンシャゼル

まだ見た中で最高のPS1。
maxywb

1
@maxywbまた、装飾だけではありません-最後のコマンドが失敗した場合、幸せそうな顔は赤に変わります(x_x)
イズカタ

4

ビルトインの一般的なソリューション(テストなど)は[1]です。

  • 使用env(すべてのシェル)

    $ env test
    external test
  • ビルトインを無効にします(bashとzshのみ):

    $ test 1 = 1 && echo "yes"
    yes
    $ enable -n test        ### for bash. Re-enable with "enable test".
    $ disable test          ### for zsh. Re-enable with "enable test".
    $ test
    external test
  • スラッシュ/を使用してコマンドを呼び出します(すべてのシェル):

    $ test 1 = 1 && echo "yes"
    yes 
    $ ~/bin/test
    external test
  • エイリアスを作成します(shopt -s expand_aliases使用されている場合を除き、bashスクリプト内で失敗します):

    $ alias test='~/bin/test'             ### remove with 'unalias test'.
    $ test
    external test

しかし、時間は組み込まれていません。

この単語timeは「予約語」であり、コマンドではなく、ビルトインでもありません。これにより、このソリューションが可能になります。

  • 言葉を引用します。これは組み込みでは機能しません。
    多くの形式の引用作業: \time "time" 'time' ti\me ti"me"など

    $  time
    
    real    0m0.000s
    user    0m0.000s
    sys     0m0.000s
    
    $ \time
    Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]
           [--portability] [--format=format] [--output=file] [--version]
           [--quiet] [--help] command [arg...]

    これはエイリアスをバイパスするのに便利です。testエイリアスが設定されている場合でも\test、PATHedコマンド(または無効になっていない場合は組み込みコマンド)が実行されます。

  • 組み込みを使用してくださいcommand(これは組み込み関数では動作しません):

    $ command time
  • ビルトインの場合と同様に、スラッシュを使用すると/機能します。

    $ /usr/bin/time
  • ビルトインの場合と同様に、エイリアスもここで機能します。

    $ alias time='command time'
    $ alias time='/usr/bin/time'

[1] ~/bin/test「外部テスト」を出力する外部実行可能ファイルがあると仮定しましょう。そしてさらに:アクティブPATHでそれ~/binが先だと仮定/binしましょう。



2

このenableコマンドを使用して、特定の組み込みを無効にすることができます。

$ enable -n kill

ただしtime、キーワードなので、これは機能しません。

$ builtin time
bash: builtin: time: not a shell builtin

そのため、エイリアスを作成して上書きします。

$ alias time=/usr/bin/time

いや。timeはシェルのキーワードであり、シェルのビルトインではありません。あなたが答えたのを見たときにenable -nが動作しないと言うために質問を編集しようとしていました。
デビッドホールデマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.