
見つからない場合に備えて、私がCDPATH
望む経路があるとしましょう。cd
.
それ自体を使わcd
ずにそれを満たす最初のパスを取得するには?bash
目的は、少なくとも私が使用しているこのバージョンのbashではサポートされないようにするcd
ことです。しかし、他のbashでも動作します。pushd
pushd
CDPATH
答え1
使用に関する懸念がcd
ある場合実際にcd
現在のシェルの作業ディレクトリの移動に関して無害に消えているサブシェルで実行されているコマンド置換を使用できます。
d=$(cd some-name)
たとえば、
$ mkdir /tmp/{a..d}
$ CDPATH=/tmp
$ cd /
$ pwd
/
$ dir=$(cd c)
$ printf '%s\n' "${dir%/*}"
/tmp
$ pwd
/
cd c
ここでは、仮説の項目がそれを満たす場合に出力をキャプチャしますCDPATH
。結果は新しい作業ディレクトリなので、そのディレクトリからそのパスエントリを返すためにCDPATH
パラメータ拡張を使用して最後のスラッシュ(デフォルトでは最も深いディレクトリの名前)を削除します。上記/tmp/c
と同じ形になります/tmp
。
答え2
あなたが意味すると仮定
特定の値が与えられたら、
$CDPATH
どのディレクトリに移動しますか?cd foo
を使用せずに見つけることができますかcd
?
いいですね。設定cd foo
したら、それぞれの値を調べて名前付きサブディレクトリを見つけます。$CDPATH
:
$CDPATH
foo
#!/bin/bash
dir=$1
cdpath=${2:-$CDPATH}
if [ -z "$cdpath" ] && [ -d "$dir" ]; then
printf '"cd %s" would take you to %s\n' "$dir" "$dir"
exit
elif [[ $dir == /* ]] || [[ $dir == ./* ]] || [[ $dir == ../* ]]; then
# special cases where $CDPATH is not used
if [ -d "$dir" ]; then
printf '"cd %s" would take you to %s (ignoring $CDPATH)\n' "$dir" "$dir"
exit
else
printf 'Did not find destination directory for %s\n' "$dir"
exit 1
fi
fi
while [ -n "$cdpath" ]; do
subdir=${cdpath%%:*}/$dir
if [ -d "$subdir" ]; then
printf '"cd %s" would take you to %s\n' "$dir" "$subdir"
exit
fi
[[ $cdpath != *:* ]] && break
cdpath=${cdpath#*:}
done
printf 'Did not find destination directory for %s\n' "$dir"
exit 1
スクリプトは、2番目の引数(またはその環境)で指定された変数の値を表示し、スクリプトのコマンドラインで最初の引数として指定された場合、ターゲットディレクトリがどこに移動するかを調べようCDPATH
とします。cd
~からCDPATH
輸出してはいけない、スクリプトは次のいずれかで呼び出す必要があります。
CDPATH=$CDPATH ./script.sh dir-name
または
./script.sh dir-name "$CDPATH"
スクリプトは最初に空であるかどうかを$CDPATH
テストします。その場合は、現在のディレクトリにcd dir
移動します。dir
また、使用のためにバイパスする必要があるいくつかの特殊なケースも処理します$CDPATH
。
空でない場合、$CDPATH
スクリプトはその値から要素を1つずつ選択し始め、指定されたディレクトリが参照パスのサブディレクトリとして存在することを確認します。
:
その値の最初の値から最後まで削除して$cdpath
最初の値を選択します。$cdpath
後で最初に取得した値まで削除するように設定します:
。これにより、ループがパスを繰り返し、$cdpath
有効なディレクトリが見つかった場合、または最終的に文字列に文字がなくなった場合にのみ終了します。:
ループを離れると、有効な目的地が見つかりませんcd
。
注:私のコードはすべてのケースを処理することはできません。関連ビットを参照してください。POSIX規格。
答え3
コマンドはどうですか?
$ find `echo $CDPATH|sed 's/://'` -name 'whatever' -print