¿Es posible anular el comando "cd" integrado en la línea de comandos?

22

Casi cada vez que 'cd' a un directorio diferente en mi máquina (en este caso, ejecutando Mac OS X 10.6.7) a través de la línea de comando (que es bash), escribo inmediatamente 'ls' para obtener la lista de contenidos en ese directorio Estoy tratando de encontrar una manera de anular 'cd' para que cambie al directorio solicitado y luego me dé la lista de una vez.

He podido obtener la funcionalidad básica que estoy buscando trabajando con la siguiente línea agregada a mi ~ / .bash_profile

function cl() { cd "$@"; ls -l; }

Esto funciona como se esperaba. Cambiando al directorio solicitado y luego mostrándome el contenido. Donde me encuentro con un problema es intentar anular "cd" en lugar de crear un nuevo comando "cl".

Las siguientes cosas no funcionan

##### Attempt 1 #####
# Hangs the command line

function cd() { cd "$@"; ls -l; }


##### Attempt 2 #####
# Hangs the command line

function cd() { 'cd' "$@"; ls -l; }


##### Attempt 3 #####
# Does not change directory. 
# Does list contents, but of the directory where you started.

function cd() { /usr/bin/cd "$@"; ls -l; }


#### Other attempts that fail in various ways #####
alias cd=cd "$@"; ls -la;
alias cd="cd '$@'; ls -la;"
alias cd='cd "$@"'; ls -la;
alias cd=/usr/bin/cd "$@"; ls -la;

También probé varias otras iteraciones que no figuran en la lista, así como hacer un alias que apunta a la función de trabajo 'cl'. Ninguno de los cuales funcionó.

Lo que he leído en la documentación habla sobre el hecho de que 'cd' no se puede ejecutar como un comando externo (que es lo que entiendo que es la forma en que la función necesitaría usarlo).

Entonces, actualmente puedo usar mi comando "cl" y obtener lo que quiero, pero la pregunta es / sigue siendo:

¿Hay alguna forma de anular el comportamiento de 'cd' para que cambie al directorio solicitado y luego haga algo más después?

Alan W. Smith
fuente

Respuestas:

30

Lo siguiente debería funcionar:

function cd() { builtin cd "$@" && ls -l; }

Dado que la función está en una sola línea, asegúrese de que se termine ;como se indica arriba para que funcione correctamente.

Garfio
fuente
No funciona para una llamada sin parámetros.
Daniel Beck
3
@DanielBeck: al menos en mi Mac OSX (10.6.7), funciona bien con una llamada sin parámetros. El comportamiento es que cambia al directorio de inicio y luego hace la lista de ese directorio. Duplicar efectivamente la funcionalidad de 'cd' simple con la nueva característica agregada al final.
Alan W. Smith
2
@ Alan True, lo probé escribiendo ese código ad-hoc en el shell. Parece que el comportamiento de cd ""(a lo que esta respuesta debería evaluar es diferente de cd "$@"vacío) $@. Perdón por la confusión.
Daniel Beck
@DanielBeck: no te preocupes.
Alan W. Smith
2
Nota: Estoy cambiando esto a la respuesta aceptada ya que es una respuesta precisa a la pregunta. El de @RichHomolka es excelente para dirigirse al director, pero este es exactamente lo que se puede poner en su archivo ~ / .bash_profile.
Alan W. Smith
10

Creo que te estás quedando atrás. Su cdfunción está llamando cd, que es ... la función.

builtinDebe saber cuál es una palabra clave que hace que la búsqueda de comandos use los Bash incorporados como cd y no su función

function cd
{
    builtin cd "$1"
    : do something else
}

Además, llamar /usr/bin/cdnunca funcionará, incluso si tal comando existiera.

Qué pasaría:

  • Mi shell Bash está en dir /bash/dir.
  • Ejecuto un comando /usr/bin/cd /dir/for/cd.
  • /usr/bin/cdva a dir /dir/for/cd.
  • /usr/bin/cd salidas
  • Bash todavía está activado /bash/dir, porque el proceso secundario /usr/bin/cdno puede afectar al padre.

También los alias son sustituciones de texto simples. Nunca pueden tener parámetros.

Rich Homolka
fuente
Sugiero builtin cd $@ && ls; ya que la cdllamada debe tener éxito para que todo lo demás tenga sentido. Además, recuerde casos especiales como cd(sin argumento).
Daniel Beck
Nota al margen: Traté de marcar esto como la respuesta aceptada, pero me dice que tengo que esperar otros 6 minutos antes de poder hacerlo. No sabía que había un retraso incorporado antes de que pudieras hacer eso.
Alan W. Smith
@ Alan Otra solución mejor podría surgir en un plazo muy razonable (es decir, esos pocos minutos que tiene que esperar). Supongo que es por eso que hay un retraso obligatorio del sistema: debe preferir la calidad a la velocidad. No debería ser demasiado inconveniente.
Daniel Beck
Y tenemos un ganador. Esto funciona como un campeón. Según @DanielBeck, cambié para usar && y lo condensé en una línea con: function cd {builtin cd "$ @" && ls -l; }
Alan W. Smith
@DanielBeck - Sí, no me preocupo por eso. Simplemente nunca lo noté antes. Puedo ver la lógica, solo me sorprendió un poco.
Alan W. Smith
6

Sugiero no anular el cd porque hay otros scripts que secuestran la función 'cd', por ejemplo, rvm. Sería mejor elegir otro nombre, como 'd', y no especificar el tipo 'incorporado' en su función; de lo contrario, el secuestrador no funcionaría. Estoy usando el siguiente código:

function d() { cd "$@" && ls;} 
Wen
fuente
Sin embargo, pensé que esto no funcionaría, según la pregunta del OP.
user305964