Por que não consigo fazer o cd para um til citado ('~')?

31

Escrevendo meu primeiro roteiro, então tenho certeza que essa é uma pergunta básica, mas alguém pode me explicar por que eu posso:

cd ~
cd bin
cd ~/bin
cd 'bin'

Mas não

cd '~'
cd '~/bin'

Eu preciso de cd para um caminho de diretório com um espaço em um dos nomes de diretório, por isso preciso das aspas (é o Windows Program Files under wine). Eu posso contornar isso com dois comandos cd , mas por que não posso colocar ~ entre aspas?

Se eu digitar cd '~' (ou cd "~" ), obtenho:

bash: cd: ~: No such file or directory
    
por B.Tanner 05.05.2018 / 13:24

4 respostas

77

Como @karel observou em sua resposta, ~ é um caractere especial e expandido por Bash no diretório inicial do usuário atual. Consulte o manual do Bash sobre "Expansão do til" ou pesquise o título "Tilde Expansion" na página man ( man bash ).

Qualquer tipo de cotação em torno do ~ impede essa expansão do til.

Para responder à sua pergunta sobre como você ainda pode usá-lo para cd em um diretório com espaços em seu nome, há algumas alternativas:

  • Omitir aspas e escapar dos espaços com barras invertidas:

    cd ~/foo/spaces\ are\ cool/bar
    
  • Cite o resto do caminho, mas omita-o em torno do til e da primeira barra:

    cd ~/"foo/spaces are cool/bar"
    

    Como você pode ver, você pode concatenar strings citadas e não-citadas no Bash simplesmente escrevendo-as uma ao lado da outra sem espaços entre elas.

  • Use a variável de ambiente $HOME em vez do til, que ainda é expandido dentro de "aspas duplas" (mas não de 'aspas simples'):

    cd "$HOME/foo/spaces are cool/bar"
    
por Byte Commander 05.05.2018 / 13:36
17

~ é um caractere especial que é interpretado pelo shell como o diretório inicial do usuário logado. '~' é interpretado pelo shell como um caractere literal ~, não como o diretório inicial do usuário que efetuou login porque colocar uma cadeia de caracteres dentro de dois caracteres de aspas simples resulta nessa string sendo interpretada como uma cadeia de texto literal.

    
por karel 05.05.2018 / 13:25
15

Este é um recurso bash chamado Expansão de til . Citando man bash :

If a word begins with an unquoted tilde character ('~'), all of the characters preceding the first unquoted slash (or all characters, if there is no unquoted slash) are considered a tilde-prefix. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible login name. If this login name is the null string, the tilde is replaced with the value of the shell parameter HOME. If HOME is unset, the home directory of the user executing the shell is substituted instead.

Para a expansão funcionar, o caractere til ~ precisa ser sem aspas, caso contrário, o caractere é obtido literalmente e cd falhará se não houver nenhum diretório denominado ~ presente no diretório atual. Veja esta resposta compreensiva para uma explicação sobre as cotações em bash . Se você precisar citar parte do caminho, você pode:

  1. cite pelo menos os caracteres que precisam ser citados com aspas simples, por exemplo

    ~/dir' 'with' 'spaces/
    

    ou

    ~/'dir with spaces/'
    
  2. cite pelo menos os caracteres que precisam ser citados com aspas duplas, por exemplo,

    ~/dir" "with" "spaces/
    

    ou

    ~/"dir with spaces/"
    
  3. cite somente os caracteres que precisam ser citados com barras invertidas, por exemplo

    ~/dir\ with\ spaces/
    

O Tilde Expansion tem algumas características mais interessantes, por exemplo:

  • ~+ expande para o valor de PWD , ou seja, o diretório de trabalho atual
  • ~- expande para o valor de OLDPWD , ou seja, o diretório de trabalho anterior
  • ~john expande para o diretório inicial associado ao nome de login "john"
por dessert 05.05.2018 / 13:36
1

Explorar usando o comando echo

A maneira mais fácil de explorar como as coisas funcionam no bash é com o comando echo . No caso de ~ use isto:

$ echo ~
/home/rick
$ echo '~'
~
$ echo "~"
~
$ echo '~'
bash: /home/rick: Is a directory

Como você pode ver, quando você usa aspas simples ou usa aspas duplas em torno de ~ , ele é interpretado literalmente como uma string e não expandido como uma variável. Quando você usa backticks ('), ele é executado como um comando e gera uma mensagem de erro.

    
por WinEunuuchs2Unix 08.05.2018 / 13:48