Actualmente lo uso para mostrar la hora actual en mi indicador de bash:
PS1=\[\e[0;32m\]\t \W>\[\e[1;37m\]
20:42:23 ~>
¿Es posible mostrar el tiempo transcurrido desde la solicitud anterior? Como:
00:00:00 ~> sleep 10
00:00:10 ~> sleep 20
00:00:20 ~>
Esto no tiene nada en común con ¿Es posible cambiar la PS1 periódicamente por un script en segundo plano?
Respuestas:
Una forma de hacerlo sería utilizar la función PROMPT_COMMAND de bash para ejecutar el código que modifica PS1. La siguiente función es una versión actualizada de mi envío original; éste usa dos variables de entorno menos y las antepone con "_PS1_" para tratar de evitar alterar variables existentes.
Ponga eso en su .bash_profile para que las cosas comiencen.
Tenga en cuenta que debe escribir con bastante rapidez para que el
sleep
parámetro coincida con el parámetro de solicitud: el tiempo realmente es la diferencia entre las solicitudes, incluido el tiempo que le lleva escribir el comando.Adición tardía:
Basado en la respuesta ahora eliminada de @Cyrus, aquí hay una versión que no satura el entorno con variables adicionales:
Adición extra tardía:
A partir de la versión 4.2 de bash (
echo $BASH_VERSION
), puede evitar lasdate
llamadas externas con una nueva cadena de formato printf; reemplazar las$(date +%s)
piezas con$(printf '%(%s)T' -1)
. A partir de la versión 4.3 , puede omitir el-1
parámetro para confiar en el comportamiento "sin argumento significa ahora ".fuente
$SECONDS
deja de rastrear el tiempo desde que se inició el shell,$SECONDS
para cada mensaje puede generar comportamientos inesperados. cualquier otra función de shell que pueda usarla por cualquier motivo asociada con la evaluación del tiempo de ejecución se comportará mal.Esto maneja el formato por cálculo, por lo tanto, si bien se expande varias veces, no hace subcapas ni tuberías.
Simplemente se trata
$PS1
como una matriz y utiliza los índices más altos para almacenar / calcular cualquier / todo estado necesario entre las indicaciones. Ningún otro estado de shell se ve afectado.Puedo desglosar un poco tal vez ...
Primero, guarde el valor actual de
$SECONDS
:A continuación, defina
$PS1[0]
ser auto recursivo de una manera que siempre establezca los valores correctos a la$PS1[1-3]
vez que autorreferencia simultáneamente. Para obtener esta parte, debe considerar el orden en que se evalúan las expresiones matemáticas de shell. Lo más importante, shell-math es siempre el último orden del día para shell-math. Antes que nada, el shell expande los valores. De esta manera, puede hacer referencia a un valor antiguo para una variable de shell en una expresión matemática después de asignarlo mediante$
.Aquí hay un ejemplo simple primero:
El shell evaluará esa declaración sustituyendo primero el valor de
$x
donde sea que$
se use la referencia de signo de dólar, y entonces la expresión se convierte en:... luego el shell agrega 5 al valor de
$x
y luego expande toda la expresiónx+10+x
, mientras que retiene solo el valor asignado en la variable de referencia. Y entonces el valor expandido de la expresión matemática es 40, pero el valor final de$x
es 15.Así es en gran medida cómo funciona la
$PS1
ecuación también, excepto que hay un nivel adicional de expansión / evaluación matemática explotado en los índices de la matriz.No estoy realmente seguro de por qué elegí usar
PS1[1]=!1
allí, supongo que probablemente fue solo una estética tonta, pero esto asigna 0 a la$PS1[1]
vez que lo expande para la sustitución de parámetros. El valor de un AND bit a bit para 0 y cualquier otra cosa siempre será 0, pero no se cortocircuita como lo hace un booleano&&
cuando el primario más a la izquierda es 0 y, por lo tanto, la expresión entre paréntesis aún se evalúa cada vez. Eso es importante, por supuesto, porque esa primera elipsis es donde se establecen los valores iniciales para$PS1[2,3]
.De todos modos,
$PS1[1]
aquí se asegura que sea 0 incluso si se manipula con los sorteos rápidos. Entre paréntesis hay ......
$PS1[2]
se le asigna la diferencia de$PS1[3]
y$SECONDS
, y$PS1[3]
se le asigna el cociente de ese valor y 3600. Todos los valores se inicializan aquí. Y entonces:... si hay al menos dos dígitos en
$PS1[3]
la expansión interna, entonces es nula, y como sabemos que$PS1[1]
es 0, entonces si$PS1[3]
se puede sustituir por nada, entonces también$PS1[1]
se expande a su valor. De esta manera, solo los valores de un solo dígito para cada iteración de$PS1[3]
asignaciones expandirán un cero inicial, y en$PS1[3]
sí mismo se expandirá el módulo 60 inmediatamente después mientras se le asigna simultáneamente el siguiente valor sucesivamente más pequeño para cada una de las horas, minutos y segundos.Enjuague y repita, hasta que
$PS1[3]
se sobrescriba la última iteración con el valor actual de, de$SECONDS
modo que pueda compararse$SECONDS
una vez más cuando se dibuje nuevamente la solicitud.fuente
La mejor solución que encontré hasta ahora es esta: https://github.com/jichu4n/bash-command-timer
Que imprime
[ 1s011 | May 25 15:33:44 BST ]
también conocido como el tiempo transcurrido en el lado derecho después del comando ejecutado, por lo que no satura tu PS1.Todo el formato de cadena y hora es configurable. Incluso el color y la precisión son configurables. Sé que puede ser un poco demasiado para un minimalista, pero es genial.
fuente