Faça com que o bash use o comando `time` externo em vez do shell embutido

27

Como faço para o bash usar o tempo binário (/ usr / bin / time) por padrão, em vez da palavra-chave shell?

which timeretorna /usr/bin/time
type timeretorna Em time is a shell keyword
execução timeestá obviamente executando a palavra-chave 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

David Holdeman
fonte

Respostas:

30

Você pode usar o commandshell interno para ignorar o processo de pesquisa normal e executar o comando fornecido como um comando externo, independentemente de outras possibilidades (embutidos 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 \rmvez de command rmou ou rm, pois, especialmente, o último pode estar associado a algo não conhecido 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, por exemplo, alias time=/usr/bin/timeé que você não está especificando o caminho completo para o timebinário, mas retornando ao mecanismo de busca de caminho usual.

O aliascomando em si pode entrar em, por exemplo, ~ / .bashrc ou /etc/bash.bashrc (este último é global para todos os usuários do sistema).

Para o caso oposto (forçando o uso do shell interno, caso haja um apelido definido), você usaria algo como builtin time, que novamente substitui o processo de pesquisa usual e executa o shell interno nomeado. A página de manual do bash menciona que isso geralmente é usado para fornecer cdfuncionalidade personalizada com uma função chamada cd, que por sua vez usa o builtin cdpara fazer a coisa real.

um CVn
fonte
Você também pode perguntar onde um comando em particular é proveniente de usar o comando type -a <cmd>.
slm
12
commandnão ignora os componentes internos (exceto zshquando não emula outras conchas). Ignora funções e essa é a principal razão de sua existência. Seu segundo papel é remover o especial em construções especiais . Ignora aliases e palavras-chave apenas porque eles são expandidos apenas na primeira posição ( zshpor exemplo, não ignora aliases globais). Não há timebash embutido. timeé uma palavra-chave que você pode fazer, por exemplo time { foo; bar; }.
Stéphane Chazelas
11
@StephaneChazelas De qualquer forma, fique à vontade para editar isso na resposta para fornecer uma descrição mais precisa. commandfunciona nesse caso em particular, como exemplificado, mas obviamente uma resposta correta é melhor do que a meia-direita.
um CVn
11
A última parte da sua resposta está errada. time não é um shell embutido, mas uma palavra-chave shell. builtin timenão funciona
Teresa e Junior
semelhante ao comando seria apenas para citá-lo:'time' echo test
mxmlnkn
9

Há um atalho no bash para contornar as palavras-chave, sem precisar especificar um caminho ou usar outro built-in 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
Izkata
fonte
8
Note-se que qualquer forma de citação ou qualquer coisa que faz com que seja não o token timevai fazer: ti\me, 'time', ti""me, ti${-##*}me, ${-+time}... Isso se aplica a qualquer palavra-chave shell.
Stéphane Chazelas
Melhor PS1 que eu já vi.
precisa saber é
11
@maxywb Além disso, não é apenas decorativo - se o último comando falhou, o rosto fica feliz em um vermelho(x_x)
Izkata
4

As soluções gerais para embutidos (por exemplo, teste) são [1] :

  • use env(todas as conchas)

    $ env test
    external test
    
  • desative 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
    
  • faça um alias (falha dentro de um script bash, exceto se shopt -s expand_aliasesfor usado):

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

Mas o tempo não está incorporado.

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

  • Cite a palavra. Isso não funciona com os built-ins.
    Muitas formas de citação funcionam:, \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 testestiver aliasado, \testexecutará o comando PATHed (ou o interno, se não tiver sido desativado).

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

    $ command time
  • Como acima, para os built-ins, usar qualquer barra /funciona:

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

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

[1] Vamos supor que exista um executável externo ~/bin/testque imprima "teste externo". E mais: vamos assumir que ~/binestá à frente /binno PATH ativo.


fonte
2

Coloque isso no seu ~/.bashrc:

alias time=/usr/bin/time

TravisThomas
fonte
2

Você pode usar o enablecomando para desativar certos built-ins.

$ enable -n kill

No entanto, timeé uma palavra-chave, portanto, isso não funcionará.

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

Portanto, você cria um alias para substituí-lo:

$ alias time=/usr/bin/time
slm
fonte
Não. time é uma palavra-chave do shell, não um shell embutido. Eu estava prestes a editar minha pergunta para dizer que enable -n não funciona quando vi que você tinha respondido.
precisa saber é o seguinte