Fazer o bash usar o comando externo 'time' em vez do shell embutido

25

Como posso fazer o bash usar o binário do tempo (/ usr / bin / time) por padrão em vez da palavra-chave shell?

which time retorna /usr/bin/time
type time retorna time is a shell keyword
A execução de time está obviamente executando a palavra-chave do 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 retorna bash: enable: time: not a shell builtin

    
por David Holdeman 10.08.2013 / 17:34

5 respostas

28

Você pode usar o shell command incorporado para ignorar o processo de pesquisa normal e executar o comando fornecido como um comando externo, independentemente de quaisquer outras possibilidades (internos do shell, aliases etc.). Isso geralmente é feito em scripts que precisam ser portáveis entre sistemas, embora provavelmente seja mais comum usar a abreviação \ (como em \rm em vez de command rm ou rm , pois o último pode ser aliado a algo que não é conhecido como 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...]
$ 

Isso pode ser usado com um alias, assim:

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

A vantagem disso sobre, por exemplo, alias time=/usr/bin/time é que você não está especificando o caminho completo para o binário time , mas retornando ao mecanismo de pesquisa de caminho usual.

O comando alias propriamente dito pode entrar em, ~ / .bashrc ou /etc/bash.bashrc (o último é global para todos os usuários no sistema).

Para o caso oposto (forçar o uso do shell embutido no caso de haver um alias definido), você usaria algo como builtin time , que novamente substitui o processo de pesquisa usual e é executado o shell nomeado incorporado. A página man bash menciona que isso é frequentemente usado para fornecer funcionalidade cd personalizada com uma função chamada cd , que por sua vez usa o cd embutido para fazer a coisa real.

    
por 10.08.2013 / 17:52
9

Existe um atalho no bash para evitar as palavras-chave, sem ter que especificar um caminho ou usar outro incorporado como command : escape com uma 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...]

Pessoalmente, acho isso mais legível e seguro, pois isso é possível:

=^_^= izkata@Izein:~$ alias command=echo
=^_^= izkata@Izein:~$ command time
time
    
por 10.08.2013 / 20:08
3

As soluções gerais para built-ins (por exemplo teste) são [1] :

  • use env (todos os shells)

    $ env test
    external test
    
  • desabilite o builtin (somente 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
    
  • use qualquer barra / para chamar o comando (todos os shells):

    $ test 1 = 1 && echo "yes"
    yes 
    $ ~/bin/test
    external test
    
  • cria um alias (falha dentro de um script bash, exceto se shopt -s expand_aliases for usado):

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

Mas o tempo não é interno.

A palavra time é uma "palavra reservada", não um comando e nem um built-in. Isso permite que essas soluções:

  • Cite a palavra. Isso não funciona com built-ins.
    Muitas formas de trabalho de cotação: \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...]
    

    Isso é útil para ignorar um alias. Mesmo se test tiver alias, \test executará o comando PATHed (ou o incorporado se não tiver sido desativado).

  • Use o command incorporado (isso não funciona com built-ins):

    $ command time
    
  • Como acima para os internos, usando qualquer barra / funciona:

    $ /usr/bin/time
    
  • Como acima para built-ins, um alias também funciona aqui:

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

[1] Vamos supor que existe um executável externo em ~/bin/test que imprime "teste externo". E mais: vamos supor que ~/bin esteja à frente de /bin no PATH ativo.

    
por 05.03.2016 / 00:39
2

Coloque isso no seu ~/.bashrc :

alias time=/usr/bin/time

    
por 10.08.2013 / 17:52
2

Você pode usar o comando enable para desativar determinados recursos internos.

$ enable -n kill

No entanto, time é uma palavra-chave, por isso não funciona.

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

Então você fica com a criação de um alias para substituí-lo:

$ alias time=/usr/bin/time
    
por 10.08.2013 / 17:44