En primer lugar, algunos antecedentes sobre ejecución de comandos en zsh es útil:
Si no se encuentra ningún comando externo pero existe una función command_not_found_handler el shell ejecuta esta función con todos los argumentos de la línea de comandos. El estado de retorno de la función se convierte en el estado del comando. Si la función desea imitar el comportamiento del shell cuando no se encuentra el comando, debe imprimir el mensaje 'command not found: cmd' en el error estándar y devolver el estado 127. Tenga en cuenta que el manejador se ejecuta en un subshell bifurcado para ejecutar un comando externo, por lo que los cambios en los directorios, los parámetros del shell, etc. no tienen efecto en el shell principal.
Por lo tanto, ahora hay dos requisitos:
- Necesito tener un
command_not_found_handler
definido;
zsh
tendrá que cargar esta función cada vez que se inicie.
El segundo punto se puede solucionar definiendo la función en ~/.zshrc
archivo. Para el primer punto he utilizado la siguiente definición:
function command_not_found_handler() {
osascript -e beep&echo "zsh: command not found: $1"&
return 127;
}
Desglose del cuerpo de la función:
osascript -e beep&
: Este comando produce el sonido de pitido por defecto de MacOS. Es el mismo sonido que se reproduce en Preferencias del Sistema > Sonido > Efectos de sonido > Funky. La ubicación real donde está presente en MacOS es /System/Library/Sounds/Funk.aiff
. He añadido &
al final de esto para ejecutar el sonido en paralelo. De lo contrario, la siguiente parte del código se retrasará en la ejecución.
echo "zsh: command not found: $1"&
: Esta es la acción por defecto que realiza zsh cuando se ejecuta un comando erróneo. Como el objetivo es producir el sonido y tener la salida del error en el código de la terminal, esto tiene que estar aquí. De nuevo, he añadido &
al final de la misma para ejecutar el sonido y el eco de este mensaje en paralelo.
return 127;
: Esto, como se menciona en el texto citado en la parte superior de la respuesta, es el código de estado esperado cuando se ejecuta un comando malo. Aunque el método me funcionó sin él, es un buen hábito de programación devolver lo que se espera.
Copiando el método en ~/.zshrc
y luego volver a hacer el abastecimiento hace que zsh
de esta función. Ahora cuando llamo a cpn
en lugar de mi alias real vpn
Mi terminal se comporta de manera más consistente con el resto del MacOS y produce el mismo sonido que en otras interacciones de la GUI, y produce un mensaje de error en la terminal.
El mérito de esta respuesta es de Comentario de @glennjackman .