$ PWDが特定のパスのサブディレクトリであることを確認する方法

$ PWDが特定のパスのサブディレクトリであることを確認する方法

たとえば、$PWD/home のサブディレクトリであることを確認します。つまり、文字列が別の文字列で始まるかどうかを確認するために、bash文字列操作を検索しています。

答え1

Bourneスタイルのシェルで文字列が別の文字列のプレフィックスであるかどうかをテストするには、次の手順を実行します。

case $PWD/ in
  /home/*) echo "home sweet home";;
  *) echo "away from home";;
esac

サフィックスまたはサブストリングテストにも同じ原則が適用されます。caseファイル名とは異なり、aまたはイニシャルを含む*すべての文字が設定で一致します。/.

この構文を実装するシェル[[ … ]](bash、ksh、zshなど)では、文字列をパターンと一致させるために使用できます。 (この[コマンドは文字列の同一性のみをテストできます。)

if [[ $PWD/ = /home/* ]]; then …

現在のディレクトリが下にあるかどうかを具体的にテストする場合、/homeシンボリックリンクがあるため、単純な部分文字列テストでは十分ではありません。

/home独自のファイルシステムの場合は、現在の.ディレクトリ()がそのファイルシステムにあるかどうかをテストします。

if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
  echo 'The current directory is on the /home filesystem'
fi

NetBSD、OpenBSD、GNU、busybox、またはtoybox(最後の3つはDebian、OpenWrt、AndroidなどのLinuxベースのシステムで一般的です)がある場合は、パスからシンボリックリンクを削除できますreadlinkreadlink -f

case $(readlink -f .)/ in "$(readlink -f /home)"/*) …

一部のシステムには次のrealpathコマンドもあります(GNUツールボックスにもあり、現在は推奨されますreadlink)。

case $(realpath .)/ in "$(realpath /home)"/*) …

シェルには修飾子を持つzsh独自の演算子もあります。realpath():P

if () [[ $1:P/ = $2:P/* ]] . /home; then …

pwdそれ以外の場合は、現在のディレクトリ表示を使用できます。ただし、シェルがcdコマンドを追跡し、「実際の」場所ではなくディレクトリにアクセスするために使用される名前を保持する場合は、組み込みシェルを使用しないように注意する必要があります。

case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
  "$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …

答え2

ディレクトリが他のディレクトリのサブディレクトリであるかどうかを確実にテストするには、文字列プレフィックスチェック以上が必要です。 Gilesの答えは、このテストを正しく実行する方法を詳しく説明しています。

しかし、単純な文字列プレフィックスチェックを本当にしたい場合(パスを正規化しましたか?)、次の方が良い選択肢です。

test "${PWD##/home/}" != "${PWD}"

"/home/"で始まると、$PWD左から削除されます。つまり、右側と一致しないため、 "!=" は true を返します。

答え3

おおよそのバージョン:

[ "${PWD:0:6}" = /home/ ]

欠点は、文字数を最初に数える必要があり、/home/このような一般的なものに置き換えることができないことです$1

編集する$VAR(@Michaelに感謝します)利用可能なものと比較するために一般化

[ "${PWD:0:${#VAR}}" = "$VAR" ]

答え4

質問がよくわかりませんが、両親が自分で見つけなければならないと思います。$PWDdirname -- "$PWD"する。親の親を見つけるには、dirname -- "$(dirname -- "$PWD")"次を実行します。

関連情報