Diferencia entre "cd -" y "cd ~ -"

56

El comando Bash

cd - 

imprime el directorio utilizado anteriormente y lo modifica.

Por otro lado, el comando Bash

cd ~-

cambia directamente al directorio utilizado anteriormente, sin hacer eco de nada.

¿Es esa la única diferencia? ¿Cuál es el caso de uso de cada uno de los comandos?

dr01
fuente
3
Te recomiendo que no uses ninguna de estas cosas difíciles. Este es tu cerebro cd ~-.
DepressedDaniel
10
@DepressedDaniel, incluso si no (planea) usar cosas complicadas, sigue siendo útil entender lo que está sucediendo detrás de escena: comprender los casos de esquina puede sacarlo de un agujero más adelante cuando intente depurar algo diferente.
anotherdave

Respuestas:

81

Hay dos cosas en juego aquí. Primero, el -solo se expande a su directorio anterior. Esto se explica en la cdsección de man bash(énfasis mío):

Un argumento de -se convierte a $ OLDPWD antes de intentar el cambio de directorio. Si se utiliza un nombre de directorio no vacío de CDPATH, o si -es el primer argumento, y el cambio de directorio es exitoso, el nombre de ruta absoluto del nuevo directorio de trabajo se escribe en la salida estándar. El valor de retorno es verdadero si el directorio se cambió con éxito; falso de lo contrario.

Entonces, un simple cd -lo moverá de regreso a su directorio anterior e imprimirá el nombre del directorio. El otro comando está documentado en la sección "Expansión de Tilde":

Si el prefijo tilde es a ~+, el valor de la variable de shell PWD reemplaza el prefijo tilde. Si el prefijo tilde es a ~-, el valor de la variable de shell OLDPWD, si está configurado, se sustituye. Si los caracteres que siguen a la tilde en el prefijo de tilde consisten en un número N, opcionalmente con el prefijo a +o a -, el prefijo de tilde se reemplaza con el elemento correspondiente de la pila de directorios, como lo mostrarían los directorios incorporados con el prefijo tilde como argumento. Si los caracteres que siguen a la tilde en el prefijo tilde consisten en un número sin un signo inicial +o -, +se supone.

Esto podría ser más fácil de entender con un ejemplo:

$ pwd
/home/terdon
$ cd ~/foo
$ pwd
/home/terdon/foo
$ cd /etc
$ pwd
/etc
$ echo ~        ## prints $HOME
/home/terdon
$ echo ~+       ## prints $PWD
/etc
$ echo ~-       ## prints $OLDPWD
/home/terdon/foo

Entonces, en general, -significa "el directorio anterior". Es cd -por eso que por sí solo lo llevará de regreso a donde sea que esté.

La principal diferencia es que cd -es específica de la cdconstrucción. Si lo intentas echo -, solo imprimirá a -. El ~-es parte de la funcionalidad de expansión tilde y se comporta de manera similar a una variable. Es por eso que puedes echo ~-y obtienes algo significativo. También puede usarlo, cd ~-pero podría usarlo en cualquier otro comando. Por ejemplo, cp ~-/* .que sería equivalente acp "$OLDPWD"/* .

terdon
fuente
1
set -ximprimir el comando expandido antes de ejecutarlo puede ser útil para ilustrar la diferencia (o puede ser indescifrablemente ruidoso cuando no lo está haciendo usted mismo paso a paso).
Peter Cordes
1
@terdon hoy aprendí.
sitilge
En resumen ... cd ~-/..funciona, cd -/..no lo hace!
Ray Foss
13

~-está sujeto a la expansión de tilde (ver man bash), entonces lo que cdve es el nombre del directorio anterior directamente. -el shell no lo expande, lo cdve directamente y se comporta como se documenta:

Un argumento de - es equivalente a $ OLDPWD. Si se utiliza un nombre de directorio no vacío de CDPATH, o si - es el primer argumento, y el cambio de directorio es exitoso, el nombre de ruta absoluto del nuevo directorio de trabajo se escribe en la salida estándar.

choroba
fuente
4

TL; DR: cd -está integrado cd, ~-es una extensión posterior de ~[name], no específico de cd.

POSIX.1-2008 Shell & Utilities se define cd -como un caso especial que es específico para el cdcomando :

Cuando -se usa a como operando, esto será equivalente al comando:

cd "$OLDPWD" && pwd

que cambia al directorio de trabajo anterior y luego escribe su nombre.

La ~-extensión se expandirá $OLDPWDantes de que se ejecute cualquier comando y se puede pasar como argumento para cualquier comando, no solo cd. Es una extensión posterior en y .

El estándar POSIX.1-2008 Shell & Utilities mencionado anteriormente también tiene una explicación detallada de la expansión de Tilde . La redacción es muy específica para permitir ~-un comportamiento indefinido dentro del alcance del estándar, donde se ~[name]refiere a $HOMEsi [name]es la cadena vacía o al directorio de inicio del usuario namesi namees un nombre de usuario válido.

Henk Langeveld
fuente