visual studio microsoft español descargar community bash shell interactive ps1

bash - microsoft - visual studio installer



Detectar comando vacío (5)

Aquí hay una posibilidad muy simple y divertida: utiliza la secuencia de escape /# de PS1 junto con expansiones de parámetros (y la forma en que Bash expande su indicador).

La secuencia de escape /# expande al número de comando del comando a ejecutar. Esto se incrementa cada vez que se ejecuta un comando. Intentalo:

$ PS1=''/# $ '' 2 $ echo hello hello 3 $ # this is a comment 3 $ 3 $ echo hello hello 4 $

Ahora, cada vez que se muestra un mensaje, Bash primero expande las secuencias de escape encontradas en PS1 , luego (siempre que se establezca el sistema de opciones de shell, que es el predeterminado), esta cadena se expande a través de la expansión de parámetros, la sustitución de comandos, la expansión aritmética , y la eliminación de cotización.

El truco es entonces tener una matriz que tendrá el k -th campo establecido (a la cadena vacía) cada vez que se ejecute el comando ( k -1) -th. Luego, utilizando las expansiones de parámetros adecuadas, podremos detectar cuándo se configuran estos campos y mostrar el código de retorno del comando anterior si el campo no está configurado. Si desea llamar a esta matriz __cmdnbary , simplemente haga lo siguiente:

PS1=''/n${__cmdnbary[/#]-$? }${__cmdnbary[/#]=}/$ ''

Mira:

$ PS1=''/n${__cmdnbary[/#]-$? }${__cmdnbary[/#]=}/$ '' 0 $ [ 2 = 3 ] 1 $ $ # it seems that it works $ echo "it works" it works 0 $

Para calificar para el desafío de respuesta más corta:

PS1=''/n${a[/#]-$? }${a[/#]=}$ ''

eso es 31 caracteres.

No use esto, por supuesto, ya que es un nombre demasiado trivial; también, /$ podría ser mejor que $ .

Parece que no te gusta que el indicador inicial sea 0 $ ; puede modificarlo muy fácilmente al inicializar la matriz __cmdnbary apropiada: colocará esto en algún lugar de su archivo de configuración:

__cmdnbary=( '''' '''' ) # Initialize the field 1! PS1=''/n${__cmdnbary[/#]-$? }${__cmdnbary[/#]=}/$ ''

Considera este PS1

PS1=''/n${_:+$? }$ ''

Aquí está el resultado de unos pocos comandos.

$ [ 2 = 2 ] 0 $ [ 2 = 3 ] 1 $ 1 $

La primera línea no muestra el estado esperado y las dos líneas siguientes muestran el código de salida correcto. Sin embargo, en la línea 3 solo se presionó Enter, por lo que me gustaría que el estado desaparezca, como la línea 1. ¿Cómo puedo hacer esto?


La variable HISTCMD se actualiza cada vez que se ejecuta un nuevo comando. Desafortunadamente, el valor se enmascara durante la ejecución de PROMPT_COMMAND (supongo que por razones relacionadas con no haber desordenado el historial con las cosas que suceden en el comando de solicitud). La solución que se me ocurrió es un poco desordenada, pero parece funcionar en mis pruebas limitadas.

# This only works if the prompt has a prefix # which is displayed before the status code field. # Fortunately, in this case, there is one. # Maybe use a no-op prefix in the worst case (!) PS1_base=$''/n'' # Functions for PROMPT_COMMAND PS1_update_HISTCMD () { # If HISTCONTROL contains "ignoredups" or "ignoreboth", this breaks. # We should not change it programmatically # (think principle of least astonishment etc) # but we can always gripe. case :$HISTCONTROL: in *:ignoredups:* | *:ignoreboth:* ) echo "PS1_update_HISTCMD(): HISTCONTROL contains ''ignoredups'' or ''ignoreboth''" >&2 echo "PS1_update_HISTCMD(): Warning: Please remove this setting." >&2 ;; esac # PS1_HISTCMD needs to contain the old value of PS1_HISTCMD2 (a copy of HISTCMD) PS1_HISTCMD=${PS1_HISTCMD2:-$PS1_HISTCMD} # PS1_HISTCMD2 needs to be unset for the next prompt to trigger properly unset PS1_HISTCMD2 } PROMPT_COMMAND=PS1_update_HISTCMD # Finally, the actual prompt: PS1=''${PS1_base#foo${PS1_HISTCMD2:=${HISTCMD%$PS1_HISTCMD}}}${_:+${PS1_HISTCMD2:+$? }}$ ''

La lógica en la solicitud es aproximadamente la siguiente:

${PS1_base#foo...}

Esto muestra el prefijo. El material en #... es útil solo por sus efectos secundarios. Queremos hacer algo de manipulación de variables sin que se muestren los valores de las variables, por lo que las ocultamos en una sustitución de cadena. (Esto mostrará cosas extrañas y posiblemente espectaculares si el valor de PS1_base alguna vez comienza con foo seguido del índice de historial de comandos actual).

${PS1_HISTCMD2:=...}

Esto asigna un valor a PS1_HISTCMD2 (si no está configurado, lo cual nos hemos asegurado de que sea así). La sustitución también se expandiría nominalmente al nuevo valor, pero la hemos ocultado en ${var#subst} como se explicó anteriormente.

${HISTCMD%$PS1_HISTCMD}

HISTCMD el valor de HISTCMD (cuando se está realizando una nueva entrada en el historial de comandos, es decir, estamos ejecutando un nuevo comando) o una cadena vacía (cuando el comando está vacío) a PS1_HISTCMD2 . Esto funciona recortando el valor HISTCMD cualquier coincidencia en PS1_HISTCMD (utilizando la sintaxis de reemplazo del sufijo ${var%subst} ).

${_:+...}

Esto es de la pregunta. Se expandirá a ... algo si el valor de $_ está establecido y no vacío (que es cuando se está ejecutando un comando, pero no, por ejemplo, si estamos realizando una asignación de variable). El "algo" debe ser el código de estado (y un espacio, para legibilidad) si PS1_HISTCMD2 no está vacío.

${PS1_HISTCMD2:+$? }

Ahí.

''$ ''

Esto es solo el sufijo del mensaje real, como en la pregunta original.

Por lo tanto, las partes clave son las variables PS1_HISTCMD que recuerda el valor anterior de HISTCMD y la variable PS1_HISTCMD2 que captura el valor de HISTCMD para que pueda accederse desde PROMPT_COMMAND , pero debe estar desactivada en PROMPT_COMMAND para que el ${PS1_HISTCMD2:=...} asignación se activará de nuevo la próxima vez que se muestre el indicador.

Jugué un poco con el intento de ocultar la salida de ${PS1_HISTCMD2:=...} pero luego me di cuenta de que, de hecho, hay algo que queremos mostrar, de modo que solo se suman a eso. No puede tener una base de PS1_base completamente vacía porque aparentemente el shell se da cuenta y ni siquiera intenta realizar una sustitución cuando no hay ningún valor; pero quizás pueda encontrar un valor ficticio (¿una secuencia de escape sin operación, quizás?) si no tiene nada más que desee mostrar. O tal vez esto podría ser refactorizado para ejecutarse con un sufijo en su lugar; pero eso probablemente será aún más complicado.

En respuesta al desafío de "respuesta más pequeña" de Anubhava, aquí está el código sin comentarios ni comprobación de errores.

PS1_base=$''/n'' PS1_update_HISTCMD () { PS1_HISTCMD=${PS1_HISTCMD2:-$PS1_HISTCMD}; unset PS1_HISTCMD2; } PROMPT_COMMAND=PS1_update_HISTCMD PS1=''${PS1_base#foo${PS1_HISTCMD2:=${HISTCMD%$PS1_HISTCMD}}}${_:+${PS1_HISTCMD2:+$? }}$ ''


Necesito usar un gran script bash-preexec.sh .

Aunque no me gustan las dependencias externas, ¿esto fue lo único que me ayudó a evitar tener 1 en $? después de presionar enter sin ejecutar ningún comando.

Esto va a tu ~/.bashrc :

__prompt_command() { local exit="$?" PS1=''/u@/h: /w /$ '' [ -n "$LASTCMD" -a "$exit" != "0" ] && PS1=''[''${red}$exit$clear"] $PS1" } PROMPT_COMMAND=__prompt_command [-f ~/.bash-preexec.sh ] && . ~/.bash-preexec.sh preexec() { LASTCMD="$1"; }


Probablemente esta no sea la mejor manera de hacerlo, pero parece estar funcionando

function pc { foo=$_ fc -l > /tmp/new if cmp -s /tmp/{new,old} || test -z "$foo" then PS1=''/n$ '' else PS1=''/n$? $ '' fi cp /tmp/{new,old} } PROMPT_COMMAND=pc

Resultado

$ [ 2 = 2 ] 0 $ [ 2 = 3 ] 1 $ $


Tengo un poco de tiempo para jugar este fin de semana. Mirando mi respuesta anterior (no buena) y otras respuestas, creo que esta puede ser la respuesta más pequeña.

Coloque estas líneas al final de su ~/.bash_profile :

PS1=''$_ret$ '' trapDbg() { local c="$BASH_COMMAND" [[ "$c" != "pc" ]] && export _cmd="$c" } pc() { local r=$? trap "" DEBUG [[ -n "$_cmd" ]] && _ret="$r " || _ret="" export _ret export _cmd= trap ''trapDbg'' DEBUG } export PROMPT_COMMAND=pc trap ''trapDbg'' DEBUG

Luego, abra un nuevo terminal y observe el comportamiento deseado en el indicador BASH :

$ uname Darwin 0 $ $ $ $ date Sun Dec 14 05:59:03 EST 2014 0 $ $ $ [ 1 = 2 ] 1 $ $ $ ls 123 ls: cannot access 123: No such file or directory 2 $ $

Explicación:

  • Esto se basa en trap ''handler'' DEBUG ganchos trap ''handler'' DEBUG y PROMPT_COMMAND trap ''handler'' DEBUG PROMPT_COMMAND .
  • PS1 está usando una variable _ret es decir, PS1=''$_ret$ '' .
  • trap comando trap ejecuta solo cuando se ejecuta un comando, pero PROMPT_COMMAND se ejecuta incluso cuando se presiona una entrada vacía.
  • trap comando trap establece una variable _cmd para el comando realmente ejecutado usando la BASH_COMMAND interna BASH_COMMAND BASH.
  • PROMPT_COMMAND hook establece _ret en "$? " Si _cmd no está vacío; de lo contrario, establece _ret en "" . Finalmente, restablece _cmd var al estado vacío.