web-dev-qa-db-ja.com

シンボリックリンクされたファイルのディレクトリにcd

スクリプトを書く前に、誰もが次のことを行う簡単な方法を知っています。

$ 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と入力できます)。

7

Zshには、そのための modifier 、または2つあります。シンボリックリンクを解決するためのArealpath を使用)と抽出するための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$ 
7
Kevin

1行:

cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))
0
diyism