NOTA: estou assumindo bash
como o shell.
Adaptar-se a outras camadas não deve ser difícil.
Obter o último comando usado é trivial: ele é armazenado no designador de evento do shell !!
, e também pode ser obtido usando os recursos incorporados do shell fc
( fc -s
) ou history
(com alguns ajustes de string: history 1 | awk '{$1=""}1'
).
Obter o tempo de execução ou o tempo de execução, no entanto, não é, a menos que alguma ação seja executada antes do comando ter sido executado. Uma vez que o comando é executado, nada pode ser feito - os cavalos foram aparafusados.
Para obter o tempo de execução:
- Defina a variável
HISTTIMEFORMAT
, o que faria com quebash
economizasse o tempo de execução no histórico e, em seguida, usasse o processamento de texto para extrair o tempo da saída dehistory
. - Use um wrapper para salvar o tempo de execução manualmente.
Para obter o tempo de execução, novamente:
- Se você tivesse definido
HISTTIMEFORMAT
antes de executar o comando, poderia analisar a saída dehistory
para obter o tempo de execução e, em seguida, calcular o tempo de execução. - Use um wrapper para executar o comando com
time
:time some-command
. O processamento da saída detime
é um pouco confuso se você quiser deixar a saída do comando intocado . - Use um wrapper para calcular o tempo de execução com base no tempo de execução salvo manualmente.
Com HISTTIMEFORMAT
definido
Se você definir a variável HISTTIMEFORMAT
, não será necessário usar um wrapper.
Primeiro, no seu .bashrc
, defina HISTTIMEFORMAT
. Você pode configurá-lo para qualquer coisa, desde que não esteja vazio. Se você não quiser que seu comando history
mostre a hora, você pode configurá-lo para um espaço ( HISTTIMEFORMAT=" "
).
Agora, há um alias presente no padrão .bashrc
do Ubuntu:
# Add an "alert" alias for long running commands. Use like so:
# sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
Podemos adaptá-lo para nossos propósitos:
alert_post ()
{
RET=$?;
END=$(date '+%s');
LAST_COMM="$(HISTTIMEFORMAT='%s '; history 1)";
START=$(awk '{print $2}' <<<"$LAST_COMM");
START_TIME=$(date -d"@$START" '+%T %D');
COMM=$(awk '{print $3}' <<<"$LAST_COMM");
notify-send --urgency=low -i "$([ $RET = 0 ] && echo terminal || echo error)" "$COMM started at $START_TIME finished in $((END - START)) seconds.";
return $RET
}
alias a=alert_post
Você pode usá-lo assim:
$ sleep 10; a
Função Wrapper
Usando uma função ou um script para envolver o comando:
alert_wrapper ()
{
START=$SECONDS;
START_TIME=$(date '+%T %D');
COMM="$1";
"$@";
RET=$?;
END=$SECONDS;
notify-send --urgency=low -i "$([ $RET = 0 ] && echo terminal || echo error)" "$COMM started at $START_TIME finished in $((END - START)) seconds."
return $RET
}
alias a=alertwrapper
Em seguida, execute seu comando prefixado com a
:
$ a sleep 10
Notas:
- Existem muitas maneiras de obter o tempo, tanto a execução quanto o tempo de execução. Usei a variável
$SECONDS
special e o comandodate
. Você poderia obter apenas o comandodate
. - Eu usei
notify-usd
, que deve estar disponível no Ubuntu padrão. Você poderia ver outras maneiras de produzir notificações. - Salvei o status de saída do comando em
$RET
e devolveu-o , pelo que deverá poder confiar nos códigos de saída:do-something; a || echo "Couldn't do something."
oua do-something || echo "Couldn't do something."
iráecho
sedo-something
tiver um estado de saída diferente de zero.