Atualmente, eu uso isso para exibir o horário atual no meu prompt do bash:
PS1=\[\e[0;32m\]\t \W>\[\e[1;37m\]
20:42:23 ~>
É possível exibir o tempo decorrido desde o prompt anterior? Tal como:
00:00:00 ~> sleep 10
00:00:10 ~> sleep 20
00:00:20 ~>
Isso não tem nada em comum. É possível alterar o PS1 periodicamente por um script em segundo plano?
Respostas:
Uma maneira de fazer isso seria usar o recurso PROMPT_COMMAND do bash para executar o código que modifica o PS1. A função abaixo é uma versão atualizada do meu envio original; este usa duas variáveis de ambiente a menos e as prefixa com "_PS1_" para tentar evitar as variáveis existentes.
Coloque isso no seu .bash_profile para iniciar as coisas.
Observe que você precisa digitar rapidamente para que o
sleep
parâmetro corresponda ao parâmetro prompt - o tempo é realmente a diferença entre os prompts, incluindo o tempo que você leva para digitar o comando.Adição tardia:
Com base na resposta agora excluída do @Cyrus, aqui está uma versão que não sobrecarrega o ambiente com variáveis extras:
Adição extra tardia:
A partir da versão 4.2 (
echo $BASH_VERSION
) do bash , é possível evitar asdate
chamadas externas com uma nova string de formato printf; substitua as$(date +%s)
peças por$(printf '%(%s)T' -1)
. A partir da versão 4.3 , é possível omitir o-1
parâmetro para confiar no comportamento "nenhum argumento significa agora ".fonte
$SECONDS
deixa de controlar o tempo desde o shell começou,$SECONDS
para cada prompt provavelmente provocará comportamentos inesperados. qualquer outra função shell que possa usá-la por qualquer motivo associado à avaliação do tempo de execução se comportará mal.Isso lida com a formatação pelo cálculo - portanto, embora se expanda várias vezes, não faz subcascas ou tubos.
Ele apenas trata
$PS1
como uma matriz e usa os índices mais altos para armazenar / calcular todo / qualquer estado necessário entre os prompts. Nenhum outro estado do shell é afetado.Eu posso dividir um pouco, talvez ...
Primeiro, salve o valor atual de
$SECONDS
:Em seguida, defina
$PS1[0]
para ser auto-recursivo de uma maneira que sempre defina os valores corretos ao$PS1[1-3]
mesmo tempo em que se auto-referencia. Para obter essa parte, você deve considerar a ordem em que as expressões shell-math são avaliadas. Mais importante, shell-math é sempre a última ordem de negócios para shell-math. Antes de tudo, o shell expande valores. Dessa maneira, você pode fazer referência a um valor antigo para uma variável de shell em uma expressão matemática depois de atribuí-la usando$
.Aqui está um exemplo simples primeiro:
O shell avaliará essa instrução substituindo primeiro o valor de
$x
onde a$
referência do cifrão é usada e, portanto, a expressão se torna:... então o shell adiciona 5 ao valor de
$x
e depois expande toda a expressão parax+10+x
, mantendo apenas o valor realmente atribuído na variável de referência. Portanto, o valor expandido da expressão matemática é 40, mas o valor final de$x
é 15.É assim também que a
$PS1
equação funciona, exceto que há um nível adicional de expansão / avaliação matemática explorada nos índices da matriz.Não sei ao certo por que escolhi usar
PS1[1]=!1
lá - acho que provavelmente era apenas uma estética boba - mas isso atribui 0 a$PS1[1]
enquanto o expande para substituição de parâmetros. O valor de um AND bit a bit para 0 e qualquer outra coisa sempre será 0, mas não funciona como um booleano&&
quando o primário mais à esquerda é 0 e, portanto, a expressão entre parênteses ainda é avaliada todas as vezes. Isso é importante, é claro, porque nessa primeira elipse é onde$PS1[2,3]
são definidos os valores iniciais .De qualquer forma,
$PS1[1]
aqui é garantido que seja 0, mesmo se for violado entre os sorteios imediatos. Dentro dos parênteses lá ......
$PS1[2]
é atribuída a diferença de$PS1[3]
e$SECONDS
, e$PS1[3]
é atribuído o quociente desse valor e 3600. Todos os valores são aqui inicializados. E entao:... se houver pelo menos dois dígitos
$PS1[3]
, a expansão interna será nula e, como sabemos que$PS1[1]
é 0, se ela$PS1[3]
puder ser substituída por nada, também$PS1[1]
será expandida para seu valor. Dessa maneira, somente os valores de um dígito para cada iteração de$PS1[3]
atribuições expandirão um zero inicial, e$PS1[3]
ele próprio será expandido no módulo 60 imediatamente depois, sendo simultaneamente atribuído o próximo valor sucessivamente menor para cada hora, minutos e segundos.Enxágüe e repita, até a última iteração, quando
$PS1[3]
é substituída pelo valor atual de,$SECONDS
para que possa ser comparada$SECONDS
mais uma vez quando o prompt for desenhado.fonte
A melhor solução que encontrei até agora é esta: https://github.com/jichu4n/bash-command-timer
Que imprime
[ 1s011 | May 25 15:33:44 BST ]
aka o tempo decorrido no lado direito após o comando executado, para não incomodar o PS1.O formato completo de sequência e hora é configurável. Até a cor e a precisão são configuráveis. Eu sei que pode ser um pouco demais para alguns minimalistas por aí, mas é bem legal.
fonte