Haga que bash use el comando externo `time` en lugar del shell incorporado


27

¿Cómo puedo hacer que bash use binary time (/ usr / bin / time) de forma predeterminada en lugar de la palabra clave de shell?

which timedevoluciones /usr/bin/time
type timedevoluciones La time is a shell keyword
ejecución timeobviamente está ejecutando la palabra clave de 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 devoluciones bash: enable: time: not a shell builtin

Respuestas:


30

Puede usar el commandshell incorporado para omitir el proceso de búsqueda normal y ejecutar el comando dado como un comando externo independientemente de cualquier otra posibilidad (shell incorporado, alias, etc.). Esto a menudo se realiza en scripts que deben ser portables en todos los sistemas, aunque probablemente más comúnmente usando la abreviatura \(como en \rmlugar de command rmo rm, ya que especialmente este último puede tener un alias a algo que no se conoce 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...]
$ 

Esto se puede usar con un alias, así:

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

La ventaja de esto sobre, por ejemplo, alias time=/usr/bin/timees que no está especificando la ruta completa al timebinario, sino que recurre al mecanismo de búsqueda de ruta habitual.

El aliascomando en sí mismo puede entrar, por ejemplo, ~ / .bashrc o /etc/bash.bashrc (este último es global para todos los usuarios del sistema).

Para el caso opuesto (forzar el uso del shell incorporado en caso de que haya un alias definido), usaría algo como builtin time, que de nuevo anula el proceso de búsqueda habitual y ejecuta el shell incorporado nombrado. La página de manual de bash menciona que esto a menudo se usa para proporcionar una cdfuncionalidad personalizada con una función llamada cd, que a su vez usa el incorporado cdpara hacer lo real.


También puede preguntar de dónde proviene un comando en particular usando el comando type -a <cmd>.
slm

12
commandno puentea los componentes incorporados (excepto zshcuando no emula otras capas). Omite funciones y esa es la razón principal de su existencia. Su segundo papel es eliminar el especial en construcciones especiales . Omite los alias y las palabras clave solo porque solo se expanden en la primera posición ( zshpor ejemplo, no omite los alias globales). No hay timebash incorporado. timees una palabra clave para que pueda hacer por ejemplo time { foo; bar; }.
Stéphane Chazelas

1
@StephaneChazelas Por supuesto, siéntase libre de editar eso en la respuesta para proporcionar una descripción más precisa. commandfunciona en este caso particular, como se ejemplifica, pero obviamente una respuesta correcta es mejor que la mitad correcta.
un CVn

1
La última parte de tu respuesta es incorrecta. el tiempo no es un shell incorporado, sino más bien una palabra clave de shell. builtin timeno funciona
Teresa e Junior

similar al comando sería simplemente citarlo:'time' echo test
mxmlnkn

9

Hay un acceso directo en bash para eludir las palabras clave, sin tener que especificar una ruta o usar otro incorporado como command: Escápelo con una barra invertida.

=^_^= 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, me parece más legible y seguro, ya que esto es posible:

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

8
Tenga en cuenta que cualquier forma de citar o cualquier cosa que hace que sea no el token timehará: ti\me, 'time', ti""me, ti${-##*}me, ${-+time}... Esto se aplica a cualquier palabra clave cáscara.
Stéphane Chazelas

La mejor PS1 que he visto hasta ahora.
maxywb

1
@maxywb Además, no es solo decorativo: si el último comando falla, la cara feliz se vuelve roja(x_x)
Izkata

4

Las soluciones generales para los elementos integrados (por ejemplo, prueba) son [1] :

  • uso env(todos los depósitos)

    $ env test
    external test
  • deshabilitar el incorporado (solo bash y 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
  • use cualquier barra inclinada /para llamar al comando (todos los shells):

    $ test 1 = 1 && echo "yes"
    yes 
    $ ~/bin/test
    external test
  • hacer un alias (falla dentro de un script bash, excepto si shopt -s expand_aliasesse usa):

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

Pero el tiempo no es un tiempo incorporado.

La palabra timees una "Palabra reservada", no un comando y tampoco una función incorporada. Eso permite estas soluciones:

  • Cita la palabra. Esto no funciona con elementos integrados.
    Muchas formas de trabajo de citas: \time "time" 'time' ti\me ti"me"etc.

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

    Esto es útil para omitir un alias. Incluso si testtiene un alias, \testejecutará el comando PATHed (o el incorporado si no se ha deshabilitado).

  • Use el incorporado command(esto no funciona con las funciones integradas):

    $ command time
  • Como se indicó anteriormente para las /funciones integradas, el uso de cualquier barra oblicua funciona:

    $ /usr/bin/time
  • Como anteriormente para las incorporadas, un alias también funciona aquí:

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

[1] Supongamos que hay un ejecutable externo ~/bin/testque imprime "prueba externa". Y además: supongamos que ~/binestá por delante /binen la RUTA activa.



2

Puede usar el enablecomando para deshabilitar ciertos elementos integrados.

$ enable -n kill

Sin embargo, timees una palabra clave, por lo que no funcionará.

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

Entonces te queda crear un alias para anularlo:

$ alias time=/usr/bin/time

no el tiempo es una palabra clave de shell, no un shell incorporado. Estaba a punto de editar mi pregunta para decir que enable -n no funciona cuando vi que había respondido.
David Holdeman
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.