Fai in modo che bash usi il comando `time` esterno anziché la shell integrata


27

Come posso fare in modo che bash usi binary time (/ usr / bin / time) di default invece della parola chiave shell?

which timeReturns /usr/bin/time
type timeReturns In time is a shell keyword
esecuzione timesta ovviamente eseguendo la parola chiave 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 ritorna bash: enable: time: not a shell builtin

Risposte:


30

È possibile utilizzare la commandshell integrata per ignorare il normale processo di ricerca ed eseguire il comando dato come comando esterno indipendentemente da qualsiasi altra possibilità (built-in della shell, alias, ecc.). Questo è spesso fatto negli script che devono essere portatili tra i sistemi, sebbene probabilmente più comunemente usando la scorciatoia \(come in \rmpiuttosto che command rmo rm, in quanto in particolare quest'ultimo può essere aliasato a qualcosa di non noto come 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...]
$ 

Questo può essere usato con un alias, in questo modo:

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

Il vantaggio di questo, ad esempio, alias time=/usr/bin/timeè che non si sta specificando il percorso completo del timebinario, ma si ricorre al normale meccanismo di ricerca del percorso.

Il aliascomando stesso può andare ad esempio in ~ / .bashrc o /etc/bash.bashrc (quest'ultimo è globale per tutti gli utenti del sistema).

Per il caso opposto (forzando l'uso della shell integrata nel caso in cui sia definito un alias), useresti qualcosa del genere builtin time, che ignora nuovamente il normale processo di ricerca ed esegue la shell incorporata. La pagina man di bash menziona che questo è spesso usato per fornire cdfunzionalità personalizzate con una funzione chiamata cd, che a sua volta usa il builtin cdper fare la cosa reale.


Puoi anche chiedere da dove proviene un comando particolare usando il comando type -a <cmd>.
slm

12
commandnon bypassa i builtin (tranne in zshquando non si emulano altre shell). Ignora le funzioni e questa è la ragione principale della sua esistenza. Il suo secondo ruolo è quello di rimuovere lo speciale in builtin speciali . Ignora alias e parole chiave solo perché sono espansi solo in prima posizione ( zshad esempio, non bypassa gli alias globali). Non c'è timebuilt-in bash. timeè una parola chiave che puoi fare per esempio time { foo; bar; }.
Stéphane Chazelas il

1
@StephaneChazelas Sicuramente sentiti libero di modificarlo nella risposta per fornire una descrizione più accurata. commandfunziona in questo caso particolare, come esemplificato, ma ovviamente una risposta corretta è migliore di una metà destra.
un CVn l'

1
L'ultima parte della tua risposta è sbagliata. time non è un built-in della shell, ma piuttosto una parola chiave della shell. builtin timenon funziona
Teresa e Junior,

simile al comando sarebbe solo per citarlo:'time' echo test
mxmlnkn

9

C'è una scorciatoia in bash per eludere le parole chiave, senza dover specificare un percorso o usare un altro builtin come command: Esci da esso con una barra rovesciata.

=^_^= 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...]

Personalmente, lo trovo più leggibile e più sicuro, in quanto ciò è possibile:

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

8
Nota che qualsiasi forma di citare o qualsiasi cosa che lo rende non il token timefarà: ti\me, 'time', ti""me, ti${-##*}me, ${-+time}... Questo vale per qualsiasi parola chiave di shell.
Stéphane Chazelas il

La migliore PS1 che abbia mai visto.
maxywb,

1
@maxywb Inoltre, non è solo decorativo - se l'ultimo comando fallisce, la faccia felice si trasforma in un rosso(x_x)
Izkata

4

Le soluzioni generali per i built-in (ad esempio test) sono [1] :

  • uso env(tutte le conchiglie)

    $ env test
    external test
  • disabilita il builtin (solo bash e 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
  • usa qualsiasi barra /per chiamare il comando (tutte le shell):

    $ test 1 = 1 && echo "yes"
    yes 
    $ ~/bin/test
    external test
  • crea un alias (fallisce all'interno di uno script bash, tranne se shopt -s expand_aliasesusato):

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

Ma il tempo non è incorporato.

La parola timeè una "parola riservata", non un comando e neppure un built-in. Ciò abilita queste soluzioni:

  • Cita la parola. Questo non funziona con i built-in.
    Molte forme di citazioni di lavoro: \time "time" 'time' ti\me ti"me"ecc.

    $  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...]

    Questo è utile per bypassare un alias. Anche se testè alias, \testeseguirà il comando PATHed (o l'integrato se non è stato disabilitato).

  • Usa il built-in command(questo non funziona con i built-in):

    $ command time
  • Come sopra per i built-in, l'utilizzo di qualsiasi barra /funziona:

    $ /usr/bin/time
  • Come sopra per i built-in, qui funziona anche un alias:

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

[1] Supponiamo che esista un eseguibile esterno ~/bin/testche stampa "test esterno". E inoltre: supponiamo che ~/binsia avanti /binnel PERCORSO attivo.



2

È possibile utilizzare il enablecomando per disabilitare alcuni built-in.

$ enable -n kill

Tuttavia timeè una parola chiave, quindi non funzionerà.

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

Quindi ti resta con la creazione di un alias per sovrascriverlo:

$ alias time=/usr/bin/time

no. time è una parola chiave della shell, non una shell incorporata. Stavo per modificare la mia domanda per dire che enable -n non funziona quando ho visto che avevi risposto.
David Holdeman,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.