Como o uso do til funciona como um atalho para o meu diretório pessoal?

30

Fiquei confuso, tentando copiar alguns arquivos de um PC para outro. Eu já entendi, mas a sintaxe ainda é confusa para mim. Isso funciona:

scp ~/Desktop/Volenteer.png jay@server.ip:~j0h/b

que coloca Volenteer.pngna pasta /home/j0h/b. No entanto, isso não funciona:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Isso também falha, fornecendo um arquivo de status de saída 1 não encontrado:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

Como faz isso:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Então, claramente, há alguma diferença entre ~e ~/ Essa diferença é a presença de/

$~/
bash: /home/j0h/: Is a directory
$ ~
bash: /home/j0h: Is a directory

Então, por que, no scp, a ~resolução é ~/? Isso é um palpite, não posso verificar o que está acontecendo. Mas parece inconsistente e, portanto, confuso. Isso é um bug no scp? ou há algo sobre til que estou faltando?

j0h
fonte
2
Apenas uma nota lado aqui, soletrou "voluntário", com um "u" em vez de um "e" :)
AER
2
Eu sou um corretor liberal.
J0h 07/08
Pergunta relacionada: askubuntu.com/q/972319/295286
Sergiy Kolodyazhnyy

Respostas:

68

~ é o seu diretório inicial.

~fooé o diretório inicial do usuário foo, se esse usuário existir, ou apenas um diretório nomeado ~foo, se esse usuário não existir.


Portanto, em:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

~Desktopserá expandido para o diretório inicial do usuário Desktop, se esse usuário existir (e geralmente não existe) ou será apenas ~Desktop(um caminho que geralmente também não existe).


Em:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

~/j0hserá expandido para um diretório nomeado j0hno jaydiretório inicial do qual, novamente, é improvável que exista.


Não é ~e ~/onde a diferença ocorre, mas em ~e ~foo.


Além disso, ~também pode ser usado para navegação no histórico de diretórios:

  • ~-é o diretório de trabalho anterior (como $OLDPWD)
  • ~+é o diretório de trabalho atual (como $PWD)

Isso não se aplica scp, pois você não pode alterar os diretórios no meio de uma scpoperação.

E se você usar pushdepopd manter uma pilha de diretórios, e seria o th diretório na pilha de diretórios, como visto na saída de . seria o diretório th do final (contando de zero, nos dois casos). Por exemplo:~N~+NNdirs~-NN

$ for i in etc usr var tmp; do pushd /$i; done
/etc ~/.vim
/usr /etc ~/.vim
/var /usr /etc ~/.vim
/tmp /var /usr /etc ~/.vim

$ dirs
/tmp /var /usr /etc ~/.vim

Em seguida, os diretórios na pilha podem ser acessados ​​usando:

/tmp /var /usr /etc ~/.vim
  ~0   ~1   ~2   ~3     ~4
 ~+0  ~+1  ~+2  ~+3    ~+4
 ~-4  ~-3  ~-2  ~-1    ~-0 
  ~+   ~-
muru
fonte
Então, ~+é sempre equivalente a .isso, certo? Parece redundante.
Curinga
1
@Wildcard bem, não exatamente. ~+e ~-use os valores de $PWDe $OLDPWD, que são caminhos absolutos. .é sempre um caminho relativo. Portanto, se houver um comando que altere o diretório de trabalho atual durante a execução, ele verá o novo caminho para .onde o caminho expandido ~-permanecerá o mesmo. tar -Cé um exemplo, embora eu admita que não consigo pensar em um bom uso ~+. $PWDseria tão bom, exceto que você não precisa citar ~+/foo/barse $PWDcontiver espaços.
Muru
1
Obrigado, isso esclarece. Na verdade, esse é um bom exemplo de caso de uso: Alguns comandos se recusam a operar em caminhos relativos por motivos de segurança; com esses comandos, você não pode usar, ./filenamemas pode usar "$PWD/filename"ou mais simplesmente ~+/filename. (E alguns comandos funcionarão em nomes de caminho relativos, mas há uma diferença funcional, como lnou tar.) #
Wildcard
21

Leia a documentação do GNU para expansão do Bash Tilde (como eu deveria ter antes da minha primeira iteração desta resposta).

~/Desktope ~j0hestão fazendo coisas fundamentalmente diferentes, o que explica por ~Desktopque não funciona:

  • Uma planície ~é substituída pela sua $HOMEvariável de ambiente atual , definida no login. Então ~resolve /home/olipara mim e ~/Desktoplê como /home/oli/Desktop. É aqui que você vê o tilda sendo mais usado.

  • ~usernameresolve a casa de que o usuário , conforme definido nas /etc/passwd. Assim, ~oliresolve /home/oli, ~j0hpode resolver, /home/j0hmas não é necessário, seu homedir pode estar em qualquer lugar.

  • ~not-a-usernamenão resolve. Porque Desktopnão é um usuário, ~Desktopnão é substituído. É tomado literalmente como um arquivo ou caminho chamado ~Desktop(que não existe aqui).

E nem é preciso dizer que tudo isso está acontecendo remotamente (seria inútil scpse fosse substituído por valores locais). Isso funciona porque o Bash não substitui ~...se for precedido por algo que não seja espaço em branco.

Oli
fonte
O que getent passwd bindiz?
muru 5/08/2015
2
"bin" é um usuário do sistema na maioria das máquinas Linux, com um diretório inicial de / bin.
fNek
1
A falha na expansão ~diré consistente com os documentos GNU: "... os caracteres no prefixo de til após o til são tratados como um possível nome de logon ... Se o nome de logon for inválido ou a expansão do til falhar, a palavra permanece inalterado ". Aqui, dirnão é o nome de um usuário neste sistema, portanto, ele permanece inalterado.
apsillers
Obrigado a todos. Eu provavelmente deveria ler os links que eu posto :) :)
Oli
4

O símbolo ~é usado como um atalho para /home/userin bash, portanto, no caso ~/Desktop/Volenteer.pngdele, é um atalho para /home/user/Desktop/Volenteer.png.

Como você pode ver /, como sempre, mostra um novo nível na hierarquia do sistema de arquivos.

Mark Kirby
fonte
3
apenas metade da direita, é uma abreviação para a variável de ambiente $ HOME. ~{user}/poderia ser qualquer caminho aleatório, conforme definido pelo arquivo de banco de dados passwd (5). Embora sim, os padrões filesytem.org colocam usuários regulares em / home, esse não é o caso de todos os usuários (ou seja, raiz em / root e serviços em / var / ... ou unixies mais antigos usando / usr em vez de / home)
Dwight Spencer
O DwightSpencer está correto. Eu mantenho vários servidores em que os usuários estão em / usr / {CLIENTNAME} / home / e são compartilhados em vários sistemas internos e remotos (todos apontam para esse diretório), portanto, apenas um sistema precisa ser mantido. E ~ aponta para esse diretório;)
Rinzwind 5/15
3
@Rinzwind eek. Devo protestar contra esse uso abusivo e sacrílego de /usr.
muru 6/08/2015
@muru hey não era minha chamada>: - D Foi uma sobra de SCO D:
Rinzwind
1
Sinceramente, gostei do uso de / usr para todas as coisas de usuário, já que era isso o que originalmente significava. O que acho hoje em dia é o uso mais sacrílego de / usr / bin como um grande depósito de lixo unificado de todos os binários (sys, user, sysop) fora dos binutils base. Afinal, / usr foi concebido como todas as coisas que os usuários têm acesso a partir de uma montagem nfs, enquanto / usr / local era o espaço do usuário local com / sbin como binários sysop e binários do sistema / bin. Entendo que / home pode ser uma partição diferente, mas também pode / usr / home / ... mantê-lo em / usr mantém-o como espaço de nome de usuário, tanto em política, implementação e mentalidade.
Dwight Spencer
3

~é uma abreviação para a variável de ambiente $HOMEna maioria dos shells compatíveis com o derivado c shell / compatível com POSIX. o uso mais comum ~é quando você faz referência ao seu próprio diretório pessoal ou ao diretório inicial de outro usuário:

cd ~ # ie shell, take me to my home folder

cd ~root # i.e. shell, take me to root's home folder

Para localizar o diretório inicial de qualquer usuário local em um sistema POSIX (UNIX, Linux, OS X, BSD) que esteja usando o banco de dados passwd (5), execute o awk da seguinte /etc/passwdmaneira:

awk -F: '{ print $1,$(NF-1) }' /etc/passwd

Isso listará cada usuário local e seu diretório inicial.

Dwight Spencer
fonte