Me gustaría implementar una función en Bash que aumente (y devuelva) un recuento con cada llamada. Desafortunadamente, esto no parece trivial ya que estoy invocando la función dentro de una subshell y, en consecuencia, no puede modificar las variables de su shell principal.
Aquí está mi intento:
PS_COUNT=0
ps_count_inc() {
let PS_COUNT=PS_COUNT+1
echo $PS_COUNT
}
ps_count_reset() {
let PS_COUNT=0
}
Esto se usaría de la siguiente manera (y, por lo tanto, mi necesidad de invocar las funciones desde una subshell):
PS1='$(ps_count_reset)> '
PS2='$(ps_count_inc) '
De esa manera, tendría un indicador numerado de varias líneas:
> echo 'this
1 is
2 a
3 test'
Linda. Pero debido a la limitación mencionada anteriormente no funciona.
Una solución que no funciona sería escribir el recuento en un archivo en lugar de una variable. Sin embargo, esto crearía un conflicto entre múltiples sesiones que se ejecutan simultáneamente. Por supuesto, podría agregar el ID de proceso del shell al nombre del archivo. Pero espero que haya una mejor solución que no saturará mi sistema con muchos archivos.

man 1 mktemp.Respuestas:
Para obtener el mismo resultado que anota en su pregunta, todo lo que se necesita es esto:
No necesitas contorsionar. Esas dos líneas lo harán todo en cualquier shell que simule algo cercano a la compatibilidad POSIX.
Pero me ha gustado esto. Y quería demostrar los fundamentos de lo que hace que esto funcione un poco mejor. Así que edité esto un poco. Lo puse
/tmppor ahora, pero creo que también me lo guardaré. Esta aquí:GUIÓN INMEDIATA:
Nota: habiendo aprendido recientemente de yash , lo construí ayer. Por alguna razón, no imprime el primer byte de cada argumento con la
%ccadena, aunque los documentos eran específicos sobre las extensiones de ancho ancho para ese formato y, por lo tanto, pueden estar relacionados, pero funciona bien con%.1sEso es todo. Hay dos cosas principales que suceden allí arriba. Y así es como se ve:
PARSING
$PWD¿Pero qué hay del incremento?
Y es gracias a POSIX-especificado
${parameter} $((expansion))que mantiene estas definiciones en el shell actual sin requerir que las establezcamos en un subshell separado, independientemente de dónde las evaluamos. Y es por eso que funciona endashyshtan bien como enbashyzsh. No utilizamos escapes dependientes de shell / terminal y dejamos que las variables se prueben a sí mismas. Eso es lo que hace que el código portátil sea rápido.El resto es bastante simple: solo incremente nuestro contador por cada vez que
$PS2se evalúe hasta que$PS1una vez más se restablezca. Me gusta esto:Entonces ahora puedo:
DASH DEMO
SH DEMO
Funciona igual en
bashosh:Como dije anteriormente, el problema principal es que debes considerar dónde haces tu cálculo. No obtiene el estado en el shell principal, por lo que no calcula allí. Obtiene el estado en la subshell, así que ahí es donde calcula. Pero haces la definición en el shell principal.
fuente
PS2? Esta es la parte difícil. No creo que su solución pueda aplicarse aquí. Si piensas lo contrario, muéstrame cómo.PS1yPS2son variables especiales en el shell que se imprimen como símbolo del sistema (pruébelo estableciendoPS1un valor diferente en una nueva ventana del shell), por lo tanto, se usan de manera muy diferente a su código. Aquí hay más información sobre su uso: linuxconfig.org/bash-prompt-basicsecho 'thisen el indicador, luego explique cómo actualizar el valor dePS2antes de escribir la comilla simple de cierre.Con este enfoque (función que se ejecuta en una subshell), no podrá actualizar el estado del proceso de shell maestro sin sufrir contorsiones. En su lugar, organice la función para que se ejecute en el proceso maestro.
El valor de la
PROMPT_COMMANDvariable se interpreta como un comando que se ejecuta antes de imprimir laPS1solicitud.por
PS2no hay nada comparable. Pero puede usar un truco en su lugar: dado que todo lo que quiere hacer es una operación aritmética, puede usar la expansión aritmética, que no implica una subshell.El resultado del cálculo aritmético termina en la solicitud. Si desea ocultarlo, puede pasarlo como un subíndice de matriz que no existe.
fuente
Es un poco intensivo de E / S, pero necesitará usar un archivo temporal para mantener el valor del recuento.
Si le preocupa la necesidad de un archivo separado por sesión de shell (lo que parece una preocupación menor; ¿realmente estará escribiendo comandos de varias líneas en dos shells diferentes al mismo tiempo?), Debe usar
mktemppara crear un nuevo archivo para cada utilizar.fuente
No puede usar una variable de shell de esta manera y ya comprende por qué. Una subshell hereda variables exactamente de la misma manera que un proceso hereda su entorno: cualquier cambio realizado se aplica solo a él y a sus hijos y no a ningún proceso ancestro.
Según otras respuestas, lo más fácil es guardar esos datos en un archivo.
Etc.
fuente
mktemp).PS2el shell expande el valor de . No tiene la oportunidad de actualizar el valor de una variable en el shell principal en ese momento.Como referencia, aquí está mi solución usando archivos temporales, que son únicos por proceso de shell, y eliminados lo antes posible (para evitar el desorden, como se alude en la pregunta):
fuente