~ 總是等於 $HOME
我知道這可能以前被問過,但我在Google上找不到。
給定
- Linux核心
- 沒有改變 $HOME 的配置
- 重擊
會
~ == $HOME
是真的嗎?
重要的是要理解
~
擴展是shell(某些shell)的一個特性,它不是一個神奇的字元,而是意味著你的主目錄,無論它在哪裡使用。它被擴展(通過shell,這是一個用於解釋命令行的應用程序),就像
$var
在執行命令之前在shell命令行中使用時在某些條件下擴展為其值一樣。該功能在 1970 年代後期首次出現在 C-shell 中(Bourne shell 沒有它,其前身 Thompson shell 也沒有),後來被添加到 Korn shell(在80 年代)。它最終被 POSIX 標準化,現在可以在大多數 shell 中使用,包括非 POSIX 的,比如
fish
.因為它在 shell 中的廣泛使用,一些非 shell 應用程序也將其辨識為主目錄。許多應用程序在它們的配置文件或它們自己的命令行 (
mutt
,slrn
,vim
…) 中就是這種情況。
bash
特別是(它是 GNU 項目的 shell,廣泛用於許多基於 Linux 的作業系統),當呼叫 as 時sh
,大多遵循關於擴展的POSIX 規則~
,並且在 POSIX 未指定的區域中,其行為主要類似於 Korn shell(的它是部分複製)。雖然
$var
在大多數地方(單引號內除外)~
都進行了擴展,但作為事後的想法,擴展僅在少數特定條件下進行了擴展。它在列表上下文中使用自己的參數時被擴展,在需要字元串的上下文中。
以下是它在哪裡擴展的幾個例子
bash
:
cmd arg ~ other arg
var=~
var=x:~:x
(POSIX 要求,用於變數PATH
,MANPATH
…)for i in ~
[[ ~ = text ]]
[[ text = ~ ]]``~
(在 AT&T 中被視為模式的擴展,ksh
但bash
自 4.0 以來沒有)。case ~ in ~) ...
${var#~}
(雖然不是在其他一些貝殼中)cmd foo=~
(雖然不是在呼叫為 時sh
,並且僅當左側的=
形狀像未引用的bash
變數名時)cmd ~/x
(顯然是 POSIX 要求的)cmd ~:x
(但不是x:~:x
或x-~-x
)a[~]=foo; echo "${a[~]} $((a[~]))"
(不在其他一些貝殼中)以下是一些未擴展的範例:
echo "~" '~'
echo ~@ ~~
(另請注意,這~u
意味著擴展到 user 的主目錄u
)。echo @~
(( HOME == ~ ))
,$(( var + ~ ))
- 與
extglob
:(case $var in @(~|other))...
雖然case $var in ~|other)
可以)。./configure --prefix=~
(因為--prefix
不是有效的變數名)cmd "foo"=~
(在bash
,因為引號)。- 當呼叫為
sh
:export "foo"=~
,env JAVA_HOME=~ cmd
…至於它擴展到什麼:
~
單獨擴展到HOME
變數的內容,或者當它沒有設置時,擴展到帳戶數據庫中目前使用者的主目錄(作為擴展,因為 POSIX 未定義該行為)。應該注意的是,在 ksh88 和
bash
4.0 之前的版本中,波浪號擴展在列表上下文中經歷了 globbing(文件名生成):$ bash -c 'echo "$HOME"' /home/***stephane*** $ bash -c 'echo ~' /home/***stephane*** /home/stephane $ bash -c 'echo "~"' ~
在通常情況下,這應該不是問題。
請注意,因為它是擴展的,所以同樣的警告適用於其他形式的擴展。
cd ~
$HOME
如果以組件開頭-
或包含..
組件則不起作用。因此,即使它不太可能產生任何影響,但嚴格來說,應該這樣寫:cd -P -- ~
甚至:
case ~ in (/*) cd -P ~;; (*) d=~; cd -P "./$d";; esac
(涵蓋
$HOME
like-
,+2
…的值)或簡單地說:cd
(
cd
無需任何參數即可將您帶到主目錄)其他 shell 有更高級的
~
擴展。例如,在 中zsh
,我們有:
~4
,~-
,~-2
(帶有完成)用於擴展目錄堆棧中的目錄(您以前去過的地方cd
)。- 動態命名目錄。您可以定義自己的機制來決定如何
~something
擴展。