スクリプトを書く前に、誰もが次のことを行う簡単な方法を知っています。
$ 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
ie、ディレクトリ/foo/bar
で、cdl
(cd link)のようなことをしたいのですが、リンクされたファイルのディレクトリ(またはリンクされたディレクトリの代わりに、それが当てはまる場合は、cd -P /bar
と入力できます)。
Zshには、そのための modifier 、または2つあります。シンボリックリンクを解決するためのA
( realpath を使用)と抽出するための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
Linuxでは、シンボリックリンクが壊れていないと仮定すると、readlink -f
を使用してパスを正規化できます。
t=$(readlink -f -- "$file")
cd "${t%/*}"
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$
1行:
cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))