シンボリックリンクファイルのディレクトリとして cd

シンボリックリンクファイルのディレクトリとして 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

つまり、ディレクトリから(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 -fLinuxでは、シンボリックリンクが破損していないと仮定して正規パスを使用できます。

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))

関連情報