Por que o cd ~ k (& tab) se expande para cd ~ kernoops quando eu já tenho uma pasta chamada "~ kernel-ppa" no pwd?

8

Eu tenho uma pasta chamada ~kernel-ppadentro ~/Downloads.

aditya@aditya-desktop:~$ cd Downloads/
aditya@aditya-desktop:~/Downloads$ ls
~kernel-ppa

Agora, quando digito cd ~ke pressiono Tabpara expansão automática, o shell o expande para, em cd ~kernoops/vez de, cd ~kernel-ppa/embora a pasta com os mesmos caracteres iniciais já esteja presente.

Para que a expansão automática funcione, preciso escapar dela \. Assim, usar cd \~ke pressionar Tabcorretamente o expande para cd \~kernel-ppa/. Mesmo usando cd \e pressionando Tabfaz o truque.

Por que é assim e por que preciso escapar? Além disso, do que estou escapando, já que nem ~é necessário para a expansão automática?

Se eu for com o fluxo, correr cd ~kernoops/e pressionar Enter, o status do terminal mudará para //:

aditya@aditya-desktop:~/Downloads$ cd ~kernoops/
aditya@aditya-desktop://$ pwd
//
aditya@aditya-desktop://$ ls
bin   cdrom  etc   initrd.img  lost+found  mnt  proc  run   srv  tmp  var
boot  dev    home  lib         media       opt  root  sbin  sys  usr  vmlinuz
aditya@aditya-desktop://$ 

Parece o /diretório, mas pwddiz que é //. O que exatamente é isso?

Aditya
fonte
@ RaduRădeanu Nem, é "/ home / Aditya / downloads / ~ kernel-ppa"
Elliott Frisch
Primeiro, "cd ~ kernoops /" leva você para "cd / home / kernoops /", que não existe. Em vez disso, você obtém "cd //", que é outra maneira de escrever "cd /" - é o diretório raiz do sistema de arquivos raiz, que parece estranho.
Elliott Frisch
Quanto ao motivo pelo qual a única escape "\\" funciona, dê uma olhada na sua pasta com treeou com lse você notará que essa é a primeira subpasta.
Elliott Frisch
@ ElliottFrisch: Acabei de notar que uma vez que ~kernel-ppaé a única pasta dentro dela; se eu apenas executar cd e pressionar tab, ele se expandirá para cd \~kernel-ppa/. Eu não preciso fugir também!
Aditya
Sim. Além disso, se você continuar pressionando TAB, percorrerá outras conclusões disponíveis.
Elliott Frisch

Respostas:

10

Como você sabe, ~expande para o diretório inicial. Mas o que você parece ter perdido é que se ~johnexpande para o diretório inicial do usuário chamado "john".

Verifique seu /etc/passwdarquivo:

% grep ker /etc/passwd
kernoops:x:107:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false

Ele tem um "usuário do sistema" nomeado kernoops(por motivos de relatórios internos de erros). Portanto, quando você digita, cd ~kTabo shell dá preferência (1) à expansão do nome do usuário antes da expansão dos diretórios locais, e você tem cd ~kernoops. Agora resulta que o diretório inicial do usuário "kernoops" é /, portanto cdé isso.

No meu shell, zshnão tenho barra dupla (2):

[:/] % cd ~kernoops/ 
[:/] % pwd
/
[:/] % cd //
[:/] % pwd
/

Como um aparte, este nome de diretório não é bem pensado. Será necessário um triplo cuidado nos scripts e o que for. A única pior ideia que posso pensar é incorporar uma guia nela ...


Notas de rodapé:

(1) In zsh, mesmo que eu tenha um diretório nomeado ~xdire nenhum usuário inicie com x; fazer cd ~xTabnão se expande e não cita o ~erro da:

[:~/tmp/x] %  mkdir \~xdir
[:~/tmp/x] % ls
~xdir
[:~/tmp/x] % cd ~xdir  
zsh: no such user or named directory: xdir
[:~/tmp/x] 1 % 

(2) Parece que me lembro que o posix fez uma exceção para a inicial //em um caminho - deve ser mantido porque alguma variante antiga do unix (usei os apollos com o Domain / OS que possuía) costumava //machine-name/...acessar sem interrupção outras máquinas ' sistema de arquivos na rede local (a segurança ainda não foi inventada). Então provavelmente o bash está bem aqui. Se você cd ///tiver o normal /no shell, no entanto.

Sim, encontrado no unix.se !

Rmano
fonte
1
Outro sistema operacional herdado conhecido usa a notação de barra dupla como essa, mas suas barras são tipicamente escritas ao contrário e não tenho certeza se ele aceita barras para acessar sistemas de arquivos remotos da rede como esse. ;-)
R .. GitHub Pare de ajudar o gelo
7

O caractere til ( ~) tem um significado especial no shell. Quando é visto em qualquer comando, é expandido para o nome do diretório inicial. Fazendo cd ~ou cd /home/adityaé o mesmo, ele acaba no seu diretório pessoal.

Ao colocar um caractere de barra invertida ( \) na frente do til, você instrui o shell a não fazer a expansão do seguinte caractere especial (isso é chamado de escape do shell). Ao fazer isso, cd \~você solicita que o shell mude para um diretório chamado ~que estaria localizado no diretório em que você está executando o comando. Assim cd \~kernel-ppa, você mudará para o diretório chamado ~kernel-ppa, que é o comportamento normal.

EDITADO: mais sobre ~

Se você escrever um nome de usuário do seu sistema após o ~, você será movido para o diretório inicial desse usuário. Fazer uma Tabexpansão depois cd ~será expandido para nomes de usuários existentes no seu sistema. Se Tabconcluir depois cd ~k, ele será expandido para ~ kernoops porque existe um usuário chamado kernoops no usuário do sistema, com um diretório inicial de /. À medida que a expansão dos cd ~kresultados ocorre cd ~kernoops/com uma barra à direita e o diretório inicial sendo ativado /, você é movido para //. Mas isso é estritamente o mesmo /que outras pessoas já disseram anteriormente.

Benoit
fonte
Obrigado pela resposta. A combinação de seu e @ respostas de Rmano limpa a confusão completamente :)
Aditya