在 Bash 的字元串變數中使用 ~ 和不使用 ~ 有什麼區別?
我正在使用一個名為dotdrop的點文件管理軟體。使用名為 的配置文件
.env
,內容如下:git_folder="~/code/Git"
.在第一次使用它之前,也可以使用腳本來設置這個 dotfile 工具,如下所示,
#!/bin/bash env1="~/Dropbox/.env" env2="/mnt/d/Dropbox/.env" if [ -f $env1 ]; then echo "Found dotdrop env file, installing dotfiles..." source $env1 eval $(grep -v "^#" $env1) dotdrop --cfg=${git_folder}/dotfiles/config.yaml install elif [ -f $env2 ]; then echo "Found dotdrop env file, installing dotfiles..." source $env2 eval $(grep -v "^#" $env2) dotdrop --cfg=${git_folder}/dotfiles/config.yaml install else echo "Pls sync environment files first!" fi
如果我將我的配置文件儲存在
~/Dropbox/.env
,當我執行腳本時,我就得到了"Pls sync environment files first!"
(如果預期條件則執行)。如果配置文件儲存在/mnt/d/Dropbox/.env
,腳本將通過 elif 條件,這是預期的。找到原因,直到我在 dubug 模式下執行腳本,並得到區別:
➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh + env1='~/Dropbox/.env' + env2=/mnt/d/Dropbox/.env + '[' -f '~/Dropbox/.env' ']' + '[' -f /mnt/d/Dropbox/.env ']' + echo 'Pls sync environment files first!' Pls sync environment files first!
~
所以,我認為和之間的區別/home/user
是原因。在我更改
~
為/home/roach
(roach 是使用者名)後,它可以工作。➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh + env1=/home/roach/Dropbox/.env + env2=/mnt/d/Dropbox/.env + '[' -f /home/roach/Dropbox/.env ']' + echo 'Found dotdrop env file, installing dotfiles...' Found dotdrop env file, installing dotfiles... + source /home/roach/Dropbox/.env ++ git_folder='~/code/Git' ++ grep -v '^#' /home/roach/Dropbox/.env + eval git_folder='~/code/Git' ++ dotdrop '--cfg=~/code/Git/dotfiles/config.yaml' install _ _ _ __| | ___ | |_ __| |_ __ ___ _ __ / _` |/ _ \| __/ _` | '__/ _ \| '_ | \__,_|\___/ \__\__,_|_| \___/| .__/ v0.22.0 |_| 0 dotfile(s) installed.
調試顯示
''
環繞+ env1='~/Dropbox/.env'
已刪除,我認為這是原因。但是,為什麼?
附加問題,
alias dotdrop="eval $(grep -v "^#" $env1) /usr/bin/dotdrop --cfg=${git_folder}/dotfiles/config.yaml install"
是一個配置添加到bashrc
,zshrc
等。如果我直接將它添加到我的腳本中它不起作用!最後,發現我必須添加
source $env
,那麼為什麼它在 bashrc 文件中工作?
~
是您的主目錄的快捷方式,但僅當它出現在引號之外的字元串開頭時。賦值運算符右側的開頭是字元串的開頭,因此env1=~/Dropbox/.env
可以工作(env1=~"/Dropbox/.env"
或任何數量的變體)。它設置env1
為/home/roach/Dropbox/.env
。但是env1="~/Dropbox/.env"
設置env1
為確切的 string~/Dropbox/.env
,它作為文件名~
在目前目錄中具有單字元名稱的目錄中查找。波浪號是縮寫,而不是萬用字元。
$env1
外部引號擴展 的值中的萬用字元env1
,但它不擴展波浪號,因為波浪號不是萬用字元。您也可以使用
env1="$HOME/Dropbox/.env"
. 這相當於env1=~/Dropbox/.env
. 字元$
(美元)在雙引號內具有特殊含義(與引號外的含義相同):它啟動變數替換(或命令或算術替換)。~
另一方面,字元(波浪號)在引號內時只是一個普通字元,甚至是雙引號。至於別名,它在 bash 腳本中不起作用的原因是 bash 預設情況下不會在腳本中擴展別名。除非您在該腳本中包含或獲取別名的定義,否則它不會在任何腳本中工作,因為別名是每個 shell 實例的屬性。它們不是流程環境的一部分。
別名在您的第二個腳本中完全起作用的原因是 dotdrop 本身在讀取其配置值時會擴展波浪號。