Разница между $HOME и '~' (тильда)?
Я всегда думал, что $HOME
и ~
были точно такими же и, следовательно, могли
использоваться взаимозаменяемо. Сегодня, когда я попытался установить pylibmc, python
привязка к memcached, на моем общем сервере использование ~
дало мне ошибку, но не
$HOME
. Я хотел бы объяснить, почему.
libmemcached - это требование для pylibmc. У меня установлен libmemcached
под моим домашним каталогом, потому что у меня нет корня на сервере. В результате
install pylibmc, мне нужно убедиться, что установка script знает, где
Найти libmemcached.
При выполнении python setup.py install --with-libmemcached=~
установка
script работает
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
который дает ошибки, которые libmemcached не может быть найден.
Если я перехожу на --with-libmemcached=$HOME
, script запускает
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
без проблем. Похоже, проблема в том, что тильда не решена. Но почему?
Ответы
Ответ 1
Оболочка заменяет ~
домашним каталогом пользователя ( update: или, возможно, домашним каталогом другого пользователя, если за ~
следует что-то, отличное от /
), но только если это первый символ слова.
--with-libmemcached=~
не имеет ~
не в начале, поэтому оболочка оставляет его в покое.
Ответ 2
Тильда является частью расширения оболочки (например, в bash, csh, zsh и т.д.). Переменная $HOME
экспортируется и может использоваться независимо от конкретной оболочки.
Ответ 3
~
расширяется ТОЛЬКО, если он является первым символом слова AND и не кавыдается
$ echo "~"
~
$ echo foo~
foo~
$ echo ~
/home/guest
$ echo ~/foo
/home/guest/foo
~username
расширяется до HOME
username
.
$ echo ~root
/root
$ echo ~invaliduser
~invaliduser
Чтобы процитировать имена файлов, вы должны использовать $HOME
или указать суффикс
$ echo "$HOME/foo bar"
/home/guest/foo bar
$ echo ~/"foo bar"
/home/guest/foo bar
$ echo ~root/"foo bar"
/root/foo bar
Обратите внимание на следующее из Расширение POSIX Tilde
Имя пути, возникающее в результате расширения тильды, должно обрабатываться как цитируемое, чтобы предотвратить его изменение путем разделения поля и расширения пути.
Ответ 4
Основное отличие:
cd /tmp
ls "$HOME" #works
ls "~" #nope
Итак, оболочка расширяет ~ только в нескольких ситуациях. В вашем случае python script simple получил ~ внутри script - не выведенное значение.
Ответ 5
Запустите следующий скрипт:
#!/bin/bash
sudo -H -u root bash<<EOF
echo $HOME
echo ~
EOF
Выход:
/home/my_current_user
/root
Вы можете видеть, что ~
раскрывается позже целевой оболочкой (запускается root
), а $HOME
заменяется исходной оболочкой (запускается my_current_user
)