web-dev-qa-db-fra.com

Fait ~ toujours égal $ home

Je sais que cela a probablement été demandé auparavant, mais je ne pouvais pas le trouver avec Google.

Étant donné

  • Noyau Linux
  • Aucune configuration qui change $ home
  • bash

Volonté ~ == $HOME Sois sincère?

41
PythonNut

Ce qui est important à comprendre, c'est que ~ L'expansion est une caractéristique de la coque (de certaines coquilles), ce n'est pas un caractère magique que signifie votre répertoire personnel où qu'il soit utilisé.

Il est étendu (par la coquille, une application utilisée pour interpréter les lignes de commande), comme $var est étendue à sa valeur dans certaines conditions lorsqu'il est utilisé dans une ligne de commande shell avant la commande.

Cette fonctionnalité est apparue pour la première fois dans la coquille C à la fin des années 1970 (la coquille de Bourne ne l'avait pas, ni son prédécesseur Thompson Shell), a été ajouté plus tard à la coquille Korn (une coquille plus récente construite sur la coquille de Bourne dans le 80). Il a finalement été normalisé par POSIX et est maintenant disponible dans la plupart des coquillages, y compris des non-POSIX, comme fish.

Parce que c'est dans une telle utilisation généralisée dans les coquilles, certaines applications non coquillantes le reconnaissent également comme signifiant le répertoire domestique. C'est le cas de nombreuses applications dans leurs fichiers de configuration ou leur propre ligne de commande (mutt, slrn, vim...).

bash spécifiquement (qui est la coquille du GNU et largement utilisé dans de nombreux systèmes d'exploitation basés sur Linux), lorsqu'il est invoqué comme sh suit principalement le - Règles de POSIX À propos de ~ L'expansion et dans les zones non spécifiées par POSIX, se comporte principalement comme la coquille Korn (dont il s'agit d'un clone de partie).

__$var est élargi dans la plupart des endroits (à l'exception de citations simples), ~ expansion, étant une réflexion après coup n'est étendue que dans quelques conditions spécifiques.

Il est élargi lorsque sur son propre argument dans les contextes de la liste, dans des contextes où une chaîne est attendue.

Voici quelques exemples d'où il est étendu à bash:

  • cmd arg ~ other arg
  • var=~
  • var=x:~:x (requis par POSIX, utilisé pour les variables telles que PATH, MANPATH...)
  • for i in ~
  • [[ ~ = text ]]
  • [[ text = ~ ]] (l'expansion de ~ étant prise comme un motif dans AT & T ksh mais pas bash depuis 4,0).
  • case ~ in ~) ...
  • ${var#~} (bien que pas dans d'autres coquilles)
  • cmd foo=~ (bien que non cas lorsqu'il soit appelé sh, et seulement quand ce qui se trouve à gauche de = est formé comme un nom de variable bash non noté)
  • cmd ~/x (requis par POSIX évidemment)
  • cmd ~:x (mais pas x:~:x ou x-~-x)
  • a[~]=foo; echo "${a[~]} $((a[~]))" (pas dans d'autres coquilles)

Voici quelques exemples où il n'est pas étendu:

  • echo "~" '~'
  • echo ~@ ~~ (Notez également que ~u est destiné à étendre au répertoire domestique de l'utilisateur u).
  • echo @~
  • (( HOME == ~ )), $(( var + ~ ))
  • avec extglob: case $var in @(~|other))... (bien que case $var in ~|other) est ok).
  • ./configure --prefix=~ (comme --prefix n'est pas un nom de variable valide)
  • cmd "foo"=~ (dans bash, à cause des guillemets).
  • lorsqu'il est invoqué comme sh: export "foo"=~, env Java_HOME=~ cmd...

Quant à ce qu'elle se développe à: ~ seul se développe au contenu de la variable HOME ou lorsqu'il n'est pas défini, au répertoire de maison de l'utilisateur actuel dans la base de données de compte (comme extension depuis que POSIX laisse ce comportement indéfini).

Il convient de noter que dans ksh88 et bash versions antérieures à 4.0, l'expansion de Tilde a subi une globbing (génération de nom de fichier) dans les contextes de la liste:

$ bash -c 'echo "$HOME"'
/home/***stephane***
$ bash -c 'echo ~'
/home/***stephane*** /home/stephane
$ bash -c 'echo "~"'
~

Cela ne devrait pas être un problème dans les cas habituels.

Notez que parce que c'est élargi, le même avertissement s'applique que d'autres formes d'extension.

cd ~

Ne fonctionne pas si $HOME commence par - ou contient .. composants. Donc, même s'il est très peu susceptible de faire une différence, à proprement parler, il faut écrire:

cd -P -- ~

Ou même:

case ~ in
  (/*) cd -P ~;;
  (*) d=~; cd -P "./$d";;
esac

(Pour couvrir les valeurs de $HOME comme -, +2...) ou simplement:

cd

(comme cd vous amène à votre annuaire de domicile sans aucun argument)

D'autres coquillages ont plus d'expansions ~ plus avancées. Par exemple, dans zsh, nous avons:

  • ~4, ~-, ~-2 (avec achèvement) Utilisé pour élargir les répertoires de votre pile de répertoires (les endroits que vous avez cd à avant).
  • répertoires nommés dynamiques. Vous pouvez définir votre propre mécanisme pour décider comment ~something est élargi.
48
Stéphane Chazelas