変数に有効なファイル名のみが含まれていることをどのように安全に確認できますか?

変数に有効なファイル名のみが含まれていることをどのように安全に確認できますか?

次のスクリプトが与えられたら、パラメータにパス()やワイルドカードなどが含まれて/home/charlesingalls/おらず、有効なファイル名のみが含まれているかどうかを確認できますか?../home/carolineingalls/

私はスクリプトが与えられたハードコーディングされたディレクトリから単一のファイルを削除できるようにしたいと思います。スクリプトは特権ユーザーとして実行されます。

#!/bin/bash

rm -f /home/charlesingalls/"$1"

ベストアンサー1

この回答では、$1サブディレクトリを含めることが許可されていると仮定します。単純なディレクトリ名である必要があるより簡単なケースに興味がある場合は、$1他の答えの1つを参照してください。


二重引用符で囲まれたワイルドカード文字は拡張されません。 isは二重引用符で囲まれているので、$1ワイルドカードは問題になりません。

シンボリックリンクは../すべてマスクできます。本物ファイルの場所です。以下に示すテストは、ファイルが実際に(表面にあるのではなく)目的のパスにあることを確認するテストです。

最新システム:使用realpath

ファイルが実際に存在することを確認するには、次のように /home/charlesingalls/しますrealpath

realpath --relative-base=/home/charlesingalls/ "/home/charlesingalls/$1"  | grep -q '^/' && exit 1

exit 1上記のコードは、指定されたファイルが$1ディレクトリの外部にある場合に実行されます/home/charlesingalls/realpathシンボリックリンクと../

realpathこれはGNU coreutilsの一部であり、すべてのLinuxシステムで使用できます。

realpath必要GNU coreutils 8.15(2012年1月)以上

はい

realpathがファイルの実際の場所をどのように../決定するかを示します(たとえば、-qgrepの実際の出力が表示されるようにgrepオプションを省略します)。

$ touch /tmp/test
$ realpath --relative-base=$HOME "$HOME/../../tmp/test" | grep '^/' && echo FAIL
/tmp/test
FAIL

シンボリックリンクに従う方法を示します。

$ ln -s /tmp/test ~/test
$ realpath --relative-base=$HOME "$HOME/test" | grep '^/' && echo FAIL
/tmp/test
FAIL

既存システム:使用readlink -e

readlinkまた、パスをコーンにし、シンボリックリンクをたどることもできます../

readlink -e "$HOME/test" | grep -q "^$HOME" || exit 1

同じサンプルファイルを使用して:

$ readlink -e "$HOME/../../tmp/test" | grep "$HOME" || echo FAIL
FAIL
$ readlink -e "$HOME/test" | grep "^$HOME" || echo FAIL
FAIL

以前のGNUシステムで利用可能なものに加えて、readlinkBSDでもバージョンを使用できます。

おすすめ記事