二重引用符で囲まれた変数拡張後のシェル glob(ワイルドカード(*))の使用

二重引用符で囲まれた変数拡張後のシェル glob(ワイルドカード(*))の使用

私はBashのすべての変数拡張を二重引用符で囲むのが最善の方法であることを読んだ。また、*二重引用符で囲まれた変数の拡張直後には、シェルグロブ(ワイルドカード())が使用できないという内容も読みました。この状況は、変数で拡張正規表現パターンの値を使用しようとすると競合します。

時折正規表現とワイルドカードを組み合わせる理由は、正規表現を最小限に抑え、個人の好みに合わせてきれいに保つためです。

私の特別な質問

mv私はphpmyadminを私のドキュメントルートにダウンロードして解凍しましたが、変数に入れた正規表現パターンで名前を変更することはできず、変数を拡張するときに機能させることはできません。正確な追跡は次のとおりです。

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}*たが、可能であれば例外なくベストプラクティスに従うことが重要です。

私の質問

変数二重引用符を拡張したままにしながら、ワイルドカードで抽出された値を引き続き使用する方法は?

ベストアンサー1

二重引用符を使用する場合、変数に格納されているファイル名globbingパターンはファイル名をワイルドカードとして指定しません。ファイル名がワイルドカードとして処理されるのを防ぐことは二重引用符であり、末尾の*ワイルドカードまたは引用符と*

私たちはしばしばWebサイトのユーザーに「変数を引用」するように指示します。これは、参照されていない変数の値がトークン化とファイル名のグロービングを受けるためです。これは一般的に私たちが望むものではありません。たとえば、パスワードはandとすることができ、[hello] world*コマンドラインのパスワードは-p $password現在のディレクトリにあるファイルに基づいて「興味深い」操作を実行します(スペース上の理由からまったく機能しない可能性があります)。質問「もご覧ください。bash / POSIXシェルで変数を引用することを忘れてしまうセキュリティリスク

ここでやりたいことは私たちが普段やりたいことと正反対だ。避けるつまり、変数のファイル名globbingパターンを使用してファイル名globbingを呼び出します。

抽出されたディレクトリの名前が安定していると信じられない場合は、より良い解決策(「クリーナー」のように)は名前が安定していることを確認することです。ただ一時ディレクトリにエントリを配置してから、場所*に移動します(おそらく、名前がわかるようにプロセスで名前を変更できます)。

これは、ファイル名のグロービングパターンのため、単に変数の周りの引用符を削除するよりも優れています。可能ディレクトリで使用可能な他のエントリに基づいて、予想される単一の名前以外の名前と一致します。

私の答えのバリエーションは次のとおりです。前の質問:

#!/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
} 

上記は5つのステップにまとめることができます。

  1. 空のディレクトリを作成し、現在の作業ディレクトリをそのディレクトリに変更します。
  2. アーカイブを入手してください。
  3. アーカイブを抽出します。
  4. アーカイブを削除します。
  5. これで、空のディレクトリにある別のフォルダ名を変更します。

おすすめ記事