Bash

在 Bash 的字元串變數中使用 ~ 和不使用 ~ 有什麼區別?

  • October 22, 2018

我正在使用一個名為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 本身在讀取其配置值時會擴展波浪號。

引用自:https://unix.stackexchange.com/questions/476959