シェル変数に絶対パスが含まれているかどうかを確認したい。
パスが存在するかどうかは関係ありません(パスが存在しない場合は作成します)が、絶対パス名を処理していることを確認したいと思います。
私のコードは次のようになります:
myfunction() {
[ magic test to see if "$1" is an absolute path ] || return 1
mkdir -p "$(dirname "$1")" || return 1
commands >> "$1"
}
または、検証する絶対パスがディレクトリであることが意図されているユースケース:
anotherfunction() {
[ same magic test ] || return 1
mkdir -p "$1"
dostuff >> "$1/somefile"
}
これがawk
の場合、次のようにチェックします:myvar ~ /^\//
必須シェルの文字列処理でこれを行うためのクリーンな方法がありますが、私はそれを思い付くのに問題があります。
(bash
固有のソリューションについて言及することは問題ありませんが、これを移植可能に行う方法も知りたいです。POSIX文字列処理で十分なようです。)
あなたはただすることができます:
case $1 in (/*) pathchk -- "$1";; (*) ! : ;; esac
それで十分でしょう。また、stderrに診断を書き込み、アクセスできないコンポーネントまたは作成できないコンポーネントの障害を返します。 pathchk
は既存のパス名ではありません-使用可能なパス名についてです。
pathchk
ユーティリティは、1つ以上のパス名が有効であることを確認します(つまり、構文エラーを引き起こさずにファイルにアクセスまたは作成するために使用できます)およびポータブル(つまり、ファイル名の切り捨ての結果はありません)。-p
オプションにより、より広範な移植性チェックが提供されます。デフォルトでは、
pathchk
ユーティリティは、基になるファイルシステムに基づいて、各pathname
オペランドの各コンポーネントをチェックします。診断は、次の各pathname
オペランドに対して記述されます。
{PATH_MAX}
バイトより長い( <limits.h> )のパス名変数値を参照)含まれているディレクトリに
{NAME_MAX}
バイトより長いコンポーネントが含まれています検索できないディレクトリ内のコンポーネントが含まれています
含まれているディレクトリで無効なコンポーネントに文字が含まれている
診断メッセージの形式は指定されていませんが、検出されたエラーと対応する
pathname
オペランドを示す必要があります。
pathname
オペランドの1つ以上のコンポーネントが、に一致するファイルである限り存在しない場合、エラーとは見なされません。不足しているコンポーネントによって指定されたpathname
は、上記で指定されたチェックのいずれにも違反しないように作成される可能性があります。
[ "$1" != "${1#/}" ] || return 1
より良い方法があるかもしれません(それが私が尋ねた理由です)。このコードは、/
の先頭の$1
を削除し、結果がnotが$1
自体と同じであることを確認します。
絶対パスは
/
で始まります/../
または/./
は含まれていません../
または./
で始まっていない/..
または/.
で終わらないしたがって、caseステートメントを使用してこれを(移植可能に)行うことができます。
ケース "x $ 1" in (x */.. | x */../* | x ../* | x * /。| x * /。/ * | x ./*) rc = 1 ;; (x /*) rc = 0 ;; ( *) rc = 1 ;; esac return $ rc
これは意図的に次のようなものを除外します
/../../../foo/../../../bar
素朴な「リーディングスラッシュ」の解釈が許すものです。
絶対パスの簡潔な定義については、POSIXの realpath を参照してください。
パターンマッチングは、ボーンのようなすべてのシェルでcase
ステートメントを使用して行われます。
is_absolute(){ case "$ 1" in /// * | //) 真/偽;; # 一部のシステムでは、// fooは特別です そしてis #絶対パスではありません。 //単独で/ /*)true ;; *)false esac }
//foo
を特別に扱わないシステムでは、最初の2つのエントリを削除します。
絶対パスの場合、それは/
で始まり、bash
について話していることを意味します(タグが示唆しているように):
$ var1='/tmp/foo'
$ var2='tmp/foo'
$ [[ "$var1" =~ ^/ ]] && echo yes || echo no
yes
$ [[ "$var2" =~ ^/ ]] && echo yes || echo no
no
POSIXは絶対パスを定義します as単一または3つ以上の/
で始まるパス名。
パス名をチェックするための pathchk というユーティリティがあるので、次のことができます。
[ -z "${1%%/*}" ] && pathchk -pP "$1"
-p
は、次のようなパスのチェックを実行するようにpathchk
に指示します。
_POSIX_PATH_MAX
を参照 )_POSIX_NAME_MAX
を参照 )-P
は、-
で始まるパスコンポーネントと空のパスから保護します。
部分文字列構文を使用して文字列の最初の文字を確認するだけです:
[[ ${var:0:1} = / ]] || return 1