Forçando um alias 'adicionado' a todos os comandos

11

É possível forçar o acréscimo de um alias de tempo (por falta de uma maneira melhor de expressá-lo) em todos os comandos em bash ?

Por exemplo, eu gostaria de ter um usuário específico que sempre que um comando é executado, ele é sempre agrupado com date antes e depois, ou time .

Isso é possível e, em caso afirmativo, como?

    
por warren 26.04.2011 / 19:20

4 respostas

10

Você pode gravar a hora em que uma linha de comando é iniciada e a hora em que um prompt é exibido. O Bash já acompanha a data de início de cada linha de comando em seu histórico e você pode observar a hora em que exibe o próximo prompt.

print_command_wall_clock_time () {
  echo Wall clock time: \
    $(($(date +%s) - $(HISTTIMEFORMAT="%s ";
                       set -o noglob;
                       set $(history 1); echo $2)))
}
PROMPT_COMMAND=print_command_wall_clock_time$'\n'"$PROMPT_COMMAND"

Isso só lhe dá a segunda resolução e apenas a hora do relógio de parede. Se você quiser uma melhor resolução, precisará usar um comando date externo que suporte o formato %N para nanossegundos e a captura DEBUG para chamar date antes de executar o comando para a hora.

call_date_before_command () {
  date_before=$(date +%s.%N)
}
print_wall_clock_time () {
  echo Wall clock time: \
    $((date +"$date_before - %s.%N" | bc))
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_command_wall_clock_time

Mesmo com a armadilha DEBUG , não acho que exista uma maneira de exibir automaticamente os tempos do processador para cada comando ou ser mais exigente que o prompt.

Se você estiver disposto a usar um shell diferente, veja como obter um relatório de tempo para cada comando no zsh (isso não é generalizado para outras tarefas):

REPORTTIME=0

Você pode definir REPORTTIME para qualquer valor inteiro, a informação de tempo será exibida apenas para comandos que usaram mais do que esses muitos segundos de tempo do processador.

Zsh usou este recurso do csh, onde a variável é chamada time .

    
por 26.04.2011 / 23:50
3

Suas opções aqui vão depender do seu shell. Em zsh há uma função de gancho conveniente chamada preexec() que é executada logo antes de qualquer comando de shell interativo. Criando uma função com esse nome, você pode fazer com que as coisas sejam executadas. Você também pode fazer o acompanhamento com uma função chamada precmd() , que será executada pouco antes do próximo prompt ser desenhado, que será logo após o término do seu comando.

Criando este par de funções, você pode ter qualquer comando arbitrário que queira executar antes e depois de quaisquer comandos que sejam emitidos no prompt. Você poderia usá-lo para registrar o uso do shell, criar bloqueios, testar o ambiente ou, no exemplo, calcular o tempo ou os recursos gastos durante a execução de um comando.

Neste exemplo, criaremos um registro de data e hora de referência antes de executar um comando usando preexec() , em seguida, calcularemos o tempo gasto na execução do comando usando precmd() e a saída antes do prompt ou logoff. Exemplo:

preexec() {
   CMDSTART=$(date +%s%N)
}
precmd() {
   CMDRUNTIME=$(($(date +%s%N)-$CMDSTART))
   echo "Last command ran for $CMDRUNTIME nanoseconds."
}

Nota: Para este exemplo específico, existe uma função integrada ainda mais fácil. Tudo o que você precisa fazer é ativar os relatórios de tempo de execução no ZSH e isso será feito automaticamente.

$ export REPORTTIME=0
$ ls -d
./
ls -BF --color=auto -d  0.00s user 0.00s system 0% cpu 0.002 total

Em uma implementação mais prática de preexec() , eu o uso, veja se o shell está rodando dentro de tmux ou screen e, em caso afirmativo, para enviar informações sobre o comando atualmente em execução upstream para ser exibido na aba nome.

Infelizmente, no bash, esse pequeno mecanismo não existe. Aqui está uma tentativa de replicar . Veja também a resposta de Gilles para um pequeno e estiloso hack.

    
por 27.04.2011 / 00:38
1

A maneira mais fácil provavelmente configuraria PROMPT_COMMAND . Consulte Variáveis de Bash :

PROMPT_COMMAND
If set, the value is interpreted as a command to execute before the printing of each primary prompt ($PS1).

Por exemplo, para evitar sobrescrever qualquer comando de prompt existente, você poderia fazer:

PROMPT_COMMAND="date ; ${PROMPT_COMMAND}"
    
por 26.04.2011 / 19:43
0

csh / tcsh tem o melhor suporte para esse recurso (e sempre teve).

  The 'time' shell variable can be set to execute the time builtin  command
  after the completion of any process that takes more than a given number
  of CPU seconds.

Em outras palavras, set time=1 imprimirá o tempo consumido (sistema, usuário, decorrido) por qualquer comando que demore mais de 1 segundo do tempo da CPU. O set time simples permitirá imprimir o tempo de todos os comandos.

    
por 07.10.2014 / 22:54