$HOME 和’~’(波浪线)之间的区别?

我一直认为 $HOME~是完全一样的,因此可以 今天,当我试图安装 Pylibmc的时候,一个巨蟒 绑定到 memcached,在我的共享服务器上使用 ~会出错,但不会 我想解释一下原因。

Libmemcached Pylibmc的一个需求,我已经安装了 Libmemcached 因为我在服务器上没有根目录 安装 Pylibmc,我需要确保安装脚本知道在哪里 找到 Libmemcached

执行 python setup.py install --with-libmemcached=~时,安装 运行脚本

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,脚本将运行

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

没有任何问题。看起来问题是波浪没有得到解决。但是为什么呢?

25579 次浏览

The tilde is part of a shell expansion (like in bash, csh, zsh, etc). The $HOME variable is exportable and can be used independent of a specific shell.

The shell replaces ~ with the user's home directory (update: or perhaps by the home directory of some other user, if ~ is followed by something other than a /), but only if it's the first character of a word.

--with-libmemcached=~ has ~ not in the beginning, so the shell leaves it alone.

The main difference is:

cd /tmp
ls "$HOME" #works
ls "~" #nope

So, shell expand the ~ only in few situations. In your case, the python script simple got ~ inside the script - not the expaded value.

~ is expanded ONLY if it is the first character of a word AND it is unquoted

$ echo "~"
~
$ echo foo~
foo~
$ echo ~
/home/guest
$ echo ~/foo
/home/guest/foo

~username is expanded to the HOME of the username.

$ echo ~root
/root
$ echo ~invaliduser
~invaliduser

To quote filenames, you should use $HOME or quote the suffix

$ echo "$HOME/foo bar"
/home/guest/foo bar
$ echo ~/"foo bar"
/home/guest/foo bar
$ echo ~root/"foo bar"
/root/foo bar

Note the following from "POSIX Tilde Expansion"

The pathname resulting from tilde expansion shall be treated as if quoted to prevent it being altered by field splitting and pathname expansion.

Run the following script:

#!/bin/bash


sudo -H -u root bash<<EOF
echo $HOME
echo ~
EOF

Output:

/home/my_current_user
/root

You can see that ~ gets expanded later, by the target shell (run by root) while $HOME gets substituted by the source shell (run by my_current_user)