Comment l'utilisation du tilde fonctionne-t-elle comme raccourci vers mon répertoire personnel?

30

J'étais confus, essayant de copier certains fichiers d'un PC à un autre. Je l'ai compris, mais la syntaxe me prête toujours à confusion. Cela marche:

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

qui met Volenteer.pngdans le dossier /home/j0h/b. Cependant, cela ne fonctionne pas:

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

Cela échoue également, donnant un fichier de statut de sortie 1 introuvable:

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

Comme cela:

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

Donc, clairement, il y a une différence entre ~et ~/ Cette différence est la présence de/

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

Alors pourquoi en scp, la ~résolution est-elle de ~/? C'est une supposition, je ne peux pas vérifier que c'est ce qui se passe. Mais cela semble incohérent, et donc déroutant. Est-ce un bug dans scp? ou y a-t-il quelque chose à propos de tilde qui me manque?

j0h
la source
2
Juste une petite note ici, c'est orthographié "volontaire", avec un "u" au lieu d'un "e" :)
AER
2
Je suis un orthographe libéral.
j0h
Question connexe: askubuntu.com/q/972319/295286
Sergiy Kolodyazhnyy

Réponses:

68

~ est votre répertoire personnel.

~fooest le répertoire personnel de l'utilisateur foo, si un tel utilisateur existe, ou simplement un répertoire nommé ~foo, si cet utilisateur n'existe pas.


Par conséquent, dans:

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

~Desktopsera étendu au répertoire personnel de l'utilisateur Desktop, si un tel utilisateur existe (et il n'existe généralement pas), ou s'il est juste ~Desktop(un chemin qui n'existe généralement pas non plus).


Dans:

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

~/j0hva se développer dans un répertoire nommé j0hdans jayle répertoire personnel de, qui, encore une fois, est peu probable.


Ce n'est pas ~et ~/où la différence se produit, mais dans ~et ~foo.


En outre, ~peut également être utilisé pour la navigation dans l'historique des répertoires:

  • ~-est le répertoire de travail précédent (comme $OLDPWD)
  • ~+est le répertoire de travail actuel (comme $PWD)

Cela ne s'applique pas à scp, car vous ne pouvez pas changer de répertoire au milieu d'une scpopération.

Et si vous utilisez pushdetpopd pour maintenir une pile de répertoires, et serait le répertoire th dans la pile de répertoires, comme on le voit dans la sortie de . serait le répertoire th de la fin (en comptant à partir de zéro, dans les deux cas). Par exemple:~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

Ensuite, les répertoires de la pile sont accessibles en utilisant:

/tmp /var /usr /etc ~/.vim
  ~0   ~1   ~2   ~3     ~4
 ~+0  ~+1  ~+2  ~+3    ~+4
 ~-4  ~-3  ~-2  ~-1    ~-0 
  ~+   ~-
muru
la source
Donc, ~+est toujours équivalent à .alors, n'est-ce pas? Semble redondant.
Wildcard
1
@Wildcard bien, pas exactement. ~+et ~-utilisez les valeurs de $PWDet $OLDPWD, qui sont des chemins absolus. .est toujours un chemin relatif. Donc, s'il y a une commande qui change le répertoire de travail actuel lors de l'exécution, elle verra le nouveau chemin pour ., où le chemin développé par ~-restera le même. tar -Cest un exemple, bien que j'avoue que je ne peux pas penser à une bonne utilisation pour ~+. $PWDserait tout aussi bon, sauf que vous n'avez pas besoin de citer ~+/foo/barsi $PWDcontient des espaces.
muru
1
Merci, cela clarifie les choses. En fait, c'est un bon exemple d'utilisation ici: certaines commandes refusent de fonctionner sur des chemins relatifs pour des raisons de sécurité; avec de telles commandes que vous ne pouvez pas utiliser ./filenamemais pouvez utiliser "$PWD/filename"ou plus simplement ~+/filename. (Et certaines commandes fonctionneront sur les chemins d'accès relatifs mais il y a une différence fonctionnelle, comme lnou tar.)
Wildcard
21

Lisez la documentation GNU pour Bash Tilde Expansion (comme je devrais l'avoir avant ma première itération de cette réponse).

~/Desktopet ~j0hfont des choses fondamentalement différentes, ce qui explique pourquoi ~Desktopcela ne fonctionne pas:

  • Un simple ~est substitué à votre $HOMEvariable d'environnement actuelle , définie lors de la connexion. Donc , ~décide de /home/olipour moi, et se ~/Desktoplit comme /home/oli/Desktop. C'est là que vous voyez le tilda le plus utilisé.

  • ~usernamese résout au domicile de cet utilisateur , comme indiqué dans /etc/passwd. Donc , ~olidécide de /home/oli, ~j0hpeut résoudre à /home/j0hmais pas neccessarily, votre homedir peut être partout.

  • ~not-a-usernamene résout pas. Parce que Desktopn'est pas un utilisateur, ~Desktopn'est pas substitué. Il est pris littéralement comme un fichier ou un chemin nommé ~Desktop(qui n'existe pas ici).

Et il va sans dire que tout cela se passe à distance (ce serait inutile scps'il était remplacé par des valeurs locales). Cela fonctionne parce que Bash ne se substituera pas ~...s'il est précédé par autre chose que des espaces.

Oli
la source
Que getent passwd bindit-on?
muru
2
"bin" est un utilisateur système sur la plupart des machines Linux, avec un répertoire personnel / bin.
fNek
1
L'échec de développement ~direst cohérent avec les documents GNU: "... les caractères dans le préfixe tilde suivant le tilde sont traités comme un nom de connexion possible ... Si le nom de connexion n'est pas valide, ou l'expansion du tilde échoue, le mot reste inchangé. " Ici, ce dirn'est pas le nom d'un utilisateur sur ce système, donc il reste inchangé.
apsillers
Merci a tous. Je devrais probablement lire les liens que je poste :)
Oli
4

Le symbole ~est utilisé comme raccourci pour /home/userdans bash, donc dans le cas où ~/Desktop/Volenteer.pngil est raccourci pour /home/user/Desktop/Volenteer.png.

Comme vous pouvez le voir, le /, comme toujours, montre un nouveau niveau dans la hiérarchie du système de fichiers.

Mark Kirby
la source
3
seulement à moitié à droite, c'est un raccourci pour la variable d'environnement $ HOME. ~{user}/pourrait simplement être n'importe quel chemin aléatoire défini par le fichier de base de données passwd (5). Bien que oui, les normes filesytem.org placent des utilisateurs réguliers dans / home, ce n'est pas le cas pour tous les utilisateurs (c'est-à-dire root dans / root, et services dans / var / ... ou des unixies plus anciens utilisant / usr au lieu de / home)
Dwight Spencer
DwightSpencer a raison. Je gère plusieurs serveurs où les utilisateurs se trouvent dans / usr / {CLIENTNAME} / home / et sont partagés sur plusieurs systèmes internes et distants (tous pointent vers ce répertoire), donc un seul système doit être maintenu. Et ~ pointe vers ce répertoire;)
Rinzwind
3
@Rinzwind eek. Je dois protester contre cette mauvaise utilisation sacrilège de /usr.
muru
@muru hey ce n'était pas MON appel>: - D C'était un reste de SCO D:
Rinzwind
1
Honnêtement, j'ai aimé l'utilisation de / usr pour toutes les choses, car c'est ce que cela signifiait à l'origine. Ce que je trouve ces jours-ci, c'est l'utilisation plus sacrilège de / usr / bin comme un grand dépotoir unifié de tous les binaires (sys, user, sysop) en dehors des binutils de base. Après tout, / usr était conçu comme tout ce que les utilisateurs ont accès à un montage nfs tandis que / usr / local était l'espace utilisateur local avec / sbin comme binaires sysop et binaires système / bin. J'obtiens que / home peut être une partition différente mais il en va de même pour / usr / home / ... le garder dans / usr le garde comme espace de noms utilisateur à la fois dans la politique, l'implémentation et l'état d'esprit.
Dwight Spencer
3

~est un raccourci pour la variable d'environnement $HOMEsur la plupart des dérivés de shell c / prenant en charge les shells conformes POSIX. l'utilisation la plus courante pour le ~référencement de votre propre répertoire personnel ou de celui d'un autre utilisateur:

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

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

Pour trouver le répertoire personnel de tout utilisateur local sur un système POSIX (UNIX, Linux, OS X, BSD) qui utilise la base de données passwd (5), exécutez awk /etc/passwdcomme ceci:

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

Cela répertoriera chaque utilisateur local et son répertoire personnel.

Dwight Spencer
la source