Regular-Expression

在雙引號變數擴展後使用 shell glob(萬用字元 (*))

  • February 14, 2018

我讀到在 Bash 中雙引號所有變數擴展是最佳實踐。我還讀到不能*在雙引號變數擴展之後立即使用 shell glob (wildcard())。當人們想要使用從變數擴展出來的正則表達式模式的值時,這些情況就會發生衝突。

我有時想將正則表達式與萬用字元結合起來的原因是為了使我的正則表達式保持最小、更整潔,符合我的個人喜好。

我的特殊問題

我將 phpmyadmin 下載到我的文件根目錄並解壓縮,但我無法mv通過我放入變數的正則表達式模式重命名它,並且在擴展其變數時可用。這是確切的跟踪:

userName@compName:/var/www/html# ll
total 11336
drwxr-xr-x  3 root root     4096 Feb 14 07:04 ./
drwxr-xr-x  3 root root     4096 Feb 14 06:56 ../
-rw-r--r--  1 root root      612 Feb 14 06:57 index.nginx-debian.html
drwxr-xr-x 12 root root     4096 Dec 23 08:50 phpMyAdmin-4.7.7-all-languages/
-rw-r--r--  1 root root 11589684 Dec 23 14:08 phpMyAdmin-latest-all-languages.zip
userName@compName:/var/www/html# echo $pma
[pP][hH][pP][mM][yY][aA][dD][mM][iI][nN]
userName@compName:/var/www/html# mv "$pma"*/ phpmyadmin/
mv: cannot stat '[pP][hH][pP][mM][yY][aA][dD][mM][iI][nN]*/': No such file or directory

如果我取消對變數擴展的引用,${pma}我確實能夠將變數擴展和正則表達式結合起來,如 中${pma}*,但如果可以的話,毫無例外地遵循最佳實踐對我來說很重要。

我的問題

我怎樣才能保持變數擴展雙引號,但仍然使用帶萬用字元的提取值?

如果雙引號,保存在變數中的文件名通配模式將不會通配文件名。阻止文件名被通配的是雙引號,而不是*末尾的萬用字元或引號和*.

我們經常告訴網站上的使用者“引用他們的變數”,我們這樣做是因為未引用變數的值會經歷分詞和文件名通配,這通常不是我們想要的。例如,根據目前目錄中存在的文件(並且由於空間的原因,它可能根本無法正常工作) ,密碼可能[hello] world*在命令行中包含會做“有趣”的事情。-p $password另請參閱問題“忘記在 bash/POSIX shell 中引用變數的安全隱患

您在這裡想要做的與我們通常想要避免的相反,即使用變數中的文件名通配模式呼叫文件名通配。

如果您確實不能依靠提取目錄的名稱來保持穩定,那麼更好的(如“更清潔”)解決方案可能是確保它是臨時目錄中唯一的東西,然後只使用*移動它就位(可能在此過程中更改其名稱,以便您確定它的名稱)。

這比簡單地刪除變數周圍的引號要好,因為文件名通配模式可能會匹配您期望的單個名稱之外的其他名稱,具體取決於目錄中可用的其他內容。

這是我對您上一個問題的回答的變體:

#!/bin/sh -ex

destdir="/var/www/html/phpmyadmin"

tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT    # remove temporary directory on termination

wget -O "$tmpdir/archive.zip" \
   "https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.zip"

cd "$tmpdir" && {
   unzip archive.zip
   rm -f archive.zip

   # The only thing in the current (temporary) directory now is the
   # directory with the unpacked zip file.

   mkdir -p "$destdir"
   mv ./* "$destdir"/phpmyAdmin
} 

以上內容可歸納為五個步驟:

  1. 創建一個空目錄(並將目前工作目錄更改為它)。
  2. 獲取存檔。
  3. 提取存檔。
  4. 刪除存檔。
  5. 現在在其他空目錄中更改單獨文件夾的名稱。

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