スクリプトを書く前に、次のことを行う簡単な方法を知っている人はいますか?
$ pwd
/foo/bar
$ ls -l
lrwxr-xr-x 1 username admin 48 Apr 17 2012 foo.sh -> /bar/foo.sh
$ cd /bar
$ ls
foo.sh
つまり、ディレクトリから(cd link)/foo/bar
などの操作を実行して、cdl
リンクされたファイルのディレクトリ(またはリンクディレクトリ(この場合は入力できますcd -P /bar
))に移動したいと思います。
答え1
zshに修飾子これを行うか、むしろ2つのことをする:A
シンボリックリンクを解決する(実際のパス)h
「頭」(すなわち、dirname
)。
cd $file(:A:h)
これは、シンボルが破損していない場合にのみ機能します。シンボリックリンクチェーンが存在すれば、最終目的地までこれに従う。シンボリックリンクを介してディレクトリに到達すると、その宛先になります(と同じcd -P
)。
zshがなく、そのreadlink
ユーティリティがあり、シンボリックリンクターゲットを含むディレクトリに変更したい場合:
cd -- "$(dirname -- "$(readlink -- "$file")")"
リンクの宛先自体がシンボリックリンクである可能性があります。リンクの最終宛先を含むディレクトリに切り替えるには、readlink
ループから呼び出すことができます。
while [ -L "$file" ]; do
target=$(readlink -- "$file")
while case $target in */) target=${target%/};; *) false;; esac; done
case $target in
*/*) cd -- "${target%/*}"; target=${target#**/};;
esac
done
readlink -f
Linuxでは、シンボリックリンクが破損していないと仮定して正規パスを使用できます。
t=$(readlink -f -- "$file")
cd "${t%/*}"
答え2
確認シンボリックリンクを使用して、readlink
そのdirname
ディレクトリをインポートできます。
cdl () {
cd "$(dirname "$(readlink "$1")")";
}
bash-3.2$ pwd
/foo/bar
bash-3.2$ ls -l
total 8
lrwxr-xr-x 1 root wheel 11 Jun 15 19:10 foo.sh -> /bar/foo.sh
bash-3.2$ cdl foo.sh
bash-3.2$ pwd
/bar
bash-3.2$
答え3
一行:
cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))