web-dev-qa-db-ja.com

シェル変数に絶対パスが含まれているかどうかを確認してください

シェル変数に絶対パスが含まれているかどうかを確認したい。

パスが存在するかどうかは関係ありません(パスが存在しない場合は作成します)が、絶対パス名を処理していることを確認したいと思います。

私のコードは次のようになります:

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文字列処理で十分なようです。)

3
Wildcard

あなたはただすることができます:

case $1 in (/*) pathchk -- "$1";; (*) ! : ;; esac

それで十分でしょう。また、stderrに診断を書き込み、アクセスできないコンポーネントまたは作成できないコンポーネントの障害を返します。 pathchk既存のパス名ではありません-使用可能なパス名についてです。

pathchkユーティリティは、1つ以上のパス名が有効であることを確認します(つまり、構文エラーを引き起こさずにファイルにアクセスまたは作成するために使用できます)およびポータブル(つまり、ファイル名の切り捨ての結果はありません)-pオプションにより、より広範な移植性チェックが提供されます。

デフォルトでは、pathchkユーティリティは、基になるファイルシステムに基づいて、各pathnameオペランドの各コンポーネントをチェックします。診断は、次の各pathnameオペランドに対して記述されます。

  • {PATH_MAX}バイトより長い( <limits.h>のパス名変数値を参照)

  • 含まれているディレクトリに{NAME_MAX}バイトより長いコンポーネントが含まれています

  • 検索できないディレクトリ内のコンポーネントが含まれています

  • 含まれているディレクトリで無効なコンポーネントに文字が含まれている

診断メッセージの形式は指定されていませんが、検出されたエラーと対応するpathnameオペランドを示す必要があります。

pathnameオペランドの1つ以上のコンポーネントが、に一致するファイルである限り存在しない場合、エラーとは見なされません。不足しているコンポーネントによって指定されたpathnameは、上記で指定されたチェックのいずれにも違反しないように作成される可能性があります。

6
mikeserv
[ "$1" != "${1#/}" ] || return 1

より良い方法があるかもしれません(それが私が尋ねた理由です)。このコードは、/の先頭の$1を削除し、結果がnot$1自体と同じであることを確認します。

6
Wildcard

絶対パスは

  • /で始まります
  • /../または/./は含まれていません
  • ../または./で始まっていない
  • /..または/.で終わらない

したがって、caseステートメントを使用してこれを(移植可能に)行うことができます。

ケース "x $ 1" in 
(x */.. | x */../* | x ../* | x * /。| x * /。/ * | x ./*)
 rc = 1 
 ;; 
(x /*)
 rc = 0 
 ;; 
( *)
 rc = 1 
 ;; 
 esac 
 return $ rc 

これは意図的に次のようなものを除外します

/../../../foo/../../../bar

素朴な「リーディングスラッシュ」の解釈が許すものです。

絶対パスの簡潔な定義については、POSIXの realpath を参照してください。

3
Thomas Dickey

パターンマッチングは、ボーンのようなすべてのシェルでcaseステートメントを使用して行われます。

 is_absolute(){
 case "$ 1" in 
 /// * | //) 真/偽;; # 一部のシステムでは、// fooは特別です そしてis 
#絶対パスではありません。 //単独で/
/*)true ;; 
 *)false 
 esac 
} 

//fooを特別に扱わないシステムでは、最初の2つのエントリを削除します。

3

絶対パスの場合、それは/で始まり、bashについて話していることを意味します(タグが示唆しているように):

$ var1='/tmp/foo'
$ var2='tmp/foo'

$ [[ "$var1" =~ ^/ ]] && echo yes || echo no
yes
$ [[ "$var2" =~ ^/ ]] && echo yes || echo no
no
2
jimmij

POSIXは絶対パスを定義します as単一または3つ以上の/で始まるパス名。

パス名をチェックするための pathchk というユーティリティがあるので、次のことができます。

[ -z "${1%%/*}" ] && pathchk -pP "$1"

-pは、次のようなパスのチェックを実行するようにpathchkに指示します。

-Pは、-で始まるパスコンポーネントと空のパスから保護します。

1
cuonglm

部分文字列構文を使用して文字列の最初の文字を確認するだけです:

[[ ${var:0:1} = / ]] || return 1
1
gardenhead