Diferença entre "cd -" e "cd ~ -"

56

O comando Bash

cd - 

imprime o diretório usado anteriormente e muda para ele.

Por outro lado, o comando Bash

cd ~-

muda diretamente para o diretório usado anteriormente, sem ecoar nada.

Essa é a única diferença? Qual é o caso de uso para cada um dos comandos?

dr01
fonte
3
Eu recomendo que você não use nenhuma dessas coisas complicadas. Este é o seu cérebro cd ~-.
DepressedDaniel
10
@DepressedDaniel, mesmo se você não planeja usar coisas complicadas, ainda é útil entender o que está acontecendo nos bastidores - entender os casos de canto pode tirar você de um buraco mais tarde ao tentar depurar algo diferente.
precisa

Respostas:

81

Há duas coisas em jogo aqui. Primeiro, o -sozinho é expandido para o diretório anterior. Isso é explicado na cdseção man bash(ênfase minha):

Um argumento de -é convertido em $ OLDPWD antes da tentativa de alteração do diretório. Se um nome de diretório não vazio do CDPATH for usado, ou se -for o primeiro argumento, e a alteração do diretório for bem-sucedida, o nome do caminho absoluto do novo diretório de trabalho será gravado na saída padrão. O valor de retorno é verdadeiro se o diretório foi alterado com sucesso; false caso contrário.

Portanto, um simples cd -retornará ao diretório anterior e imprimirá o nome do diretório. O outro comando está documentado na seção "Expansão de til":

Se o prefixo til for a ~+, o valor da variável de shell PWD substituirá o prefixo til. Se o prefixo til for a ~-, o valor da variável de shell OLDPWD, se estiver definido, será substituído. Se os caracteres que seguem o til no prefixo do til consistirem em um número N, opcionalmente prefixado por a +ou a -, o prefixo do til será substituído pelo elemento correspondente da pilha de diretórios, como seria exibido pelos diretórios internos chamados com o prefixo til como argumento. Se os caracteres que seguem o til no prefixo de til consistem em um número sem avanço +ou -, +é assumido.

Isso pode ser mais fácil de entender com um exemplo:

$ 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

Então, em geral, os -meios "o diretório anterior". É cd -por isso que, por si só, o levará de volta para onde você estava.

A principal diferença é que cd -é específico para o cdbuiltin. Se você tentar echo -, apenas imprimirá a -. Isso ~-faz parte da funcionalidade de expansão til e se comporta de maneira semelhante a uma variável. É por isso que você pode echo ~-e obtém algo significativo. Você também pode usá-lo, cd ~-mas também pode usá-lo em qualquer outro comando. Por exemplo, o cp ~-/* .que seria equivalente acp "$OLDPWD"/* .

terdon
fonte
11
set -xpara imprimir o comando expandido antes de executá-lo, pode ser útil ilustrar a diferença (ou pode ser extremamente barulhento quando você não está fazendo isso sozinho, uma etapa de cada vez).
Peter Cordes
11
@terdon hoje eu aprendi.
sitilge
Em suma ... cd ~-/..funciona, cd -/..não!
Ray Foss
13

~-está sujeito à expansão til (consulte man bash), então o que cdvê é o nome do diretório anterior diretamente. -não é expandido pelo shell, o cdvê diretamente e se comporta como documentado:

Um argumento de - é equivalente a $ OLDPWD. Se um nome de diretório não vazio do CDPATH for usado, ou se - for o primeiro argumento e a alteração do diretório for bem-sucedida, o nome do caminho absoluto do novo diretório de trabalho será gravado na saída padrão.

choroba
fonte
4

TL; DR: cd -está embutido cd, ~-é uma extensão posterior ~[name], não específica para cd.

O POSIX.1-2008 Shell & Utilities define cd -como um caso especial específico para o cdcomando :

Quando a -é usado como operando, isso deve ser equivalente ao comando:

cd "$OLDPWD" && pwd

que muda para o diretório de trabalho anterior e depois escreve seu nome.

A ~-extensão será expandida para $OLDPWDantes de qualquer comando ser executado e pode ser passada como argumento para qualquer comando, não apenas cd. É uma extensão posterior no e no .

O mencionado padrão POSIX.1-2008 Shell & Utilities também possui uma explicação elaborada da expansão Tilde . A redação é muito específica para permitir um ~-comportamento indefinido no escopo do padrão, onde ~[name]se refere a $HOMEse [name]é a sequência vazia ou o diretório inicial do usuário namese namefor um nome de usuário válido.

Henk Langeveld
fonte