J'avais toujours pensé que $HOME
et ~
étaient exactement les mêmes et pouvaient donc être utilisés de manière interchangeable. Aujourd'hui, quand j'ai essayé d'installer pylibmc, une liaison python avec memcached, sur mon serveur partagé, l'utilisation de ~
m'a donné une erreur mais pas $HOME
. Je voudrais expliquer pourquoi.
libmemcached est une exigence pour pylibmc. J'ai libmemcached installé sous mon répertoire personnel car je n'ai pas de racine sur le serveur. Par conséquent, pour installer pylibmc, je dois m'assurer que le script d'installation sait où trouver libmemcached.
Lors de l'exécution de python setup.py install --with-libmemcached=~
, le script d'installation s'exécute
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall\ -Wstrict-prototypes -fPIC -DUSE_ZLIB -I ~/include\ -I/usr/local/include/python2.7 -c _pylibmcmodule.c\ -O build/temp.linux-i686-2.7/_pylibmcmodule.o -fno-strict-aliasing
ce qui donne les erreurs que libmemcached est introuvable.
Si je passe à --with-libmemcached=$HOME
, le script s'exécute
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall\ -Wstrict-prototypes -fPIC -DUSE_ZLIB -I/home/waterbotte/include\ -I/usr/local/include/python2.7 -c _pylibmcmodule.c\ -O build/temp.linux-i686-2.7/_pylibmcmodule.o -fno-strict-aliasing
sans aucun probléme. Il semble que le problème est que le tilde ne soit pas résolu. Mais pourquoi?
Le Shell remplace ~
avec le répertoire personnel de l'utilisateur (mise à jour: ou peut-être par le répertoire personnel d'un autre utilisateur, si ~
est suivi par autre chose qu'un /
), mais uniquement s'il s'agit du premier caractère d'un mot.
--with-libmemcached=~
a ~
pas au début, donc le Shell le laisse tranquille.
Le tilde fait partie d'un expansion du shell (comme dans bash, csh, zsh, etc.). Le $HOME
la variable est exportable et peut être utilisée indépendamment d'un shell spécifique.
~
est développé UNIQUEMENT s'il s'agit du premier caractère d'un mot ET qu'il n'est pas cité
$ echo "~"
~
$ echo foo~
foo~
$ echo ~
/home/guest
$ echo ~/foo
/home/guest/foo
~username
est étendu au HOME
du username
.
$ echo ~root
/root
$ echo ~invaliduser
~invaliduser
Pour citer des noms de fichiers, vous devez utiliser $HOME
ou citez le suffixe
$ echo "$HOME/foo bar"
/home/guest/foo bar
$ echo ~/"foo bar"
/home/guest/foo bar
$ echo ~root/"foo bar"
/root/foo bar
Notez ce qui suit de "POSIX Tilde Expansion"
Le nom de chemin résultant de l'expansion du tilde doit être traité comme s'il était cité pour éviter qu'il ne soit modifié par la division du champ et l'expansion du nom de chemin.
La principale différence est:
cd /tmp
ls "$HOME" #works
ls "~" #nope
Ainsi, Shell n'élargit le ~ que dans quelques situations. Dans votre cas, le script python simple a obtenu ~ à l'intérieur du script - pas la valeur expadée.
Exécutez le script suivant:
#!/bin/bash
Sudo -H -u root bash<<EOF
echo $HOME
echo ~
EOF
Production:
/home/my_current_user
/root
Tu peux voir ça ~
obtient ( développé plus tard, par le shell cible (exécuté par root
) tandis que $HOME
obtient ( substitué par le shell source (exécuté par my_current_user
)