CD zum Verzeichnis einer symbolisch verknüpften Datei

7

Bevor ich ein Skript schreibe, kennt jeder eine einfache Möglichkeit, Folgendes zu tun:

$ 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

dh im Verzeichnis /foo/barmöchte ich so etwas wie cdl(CD-Link) machen, das mich zum Verzeichnis der verknüpften Datei (oder alternativ zum verknüpften Verzeichnis, falls dies der Fall wäre - wenn ich es wäre) führen würde könnte tippen cd -P /bar).

Chauncey Garrett
quelle
Darf ich fragen, was Ihre Motivation dafür ist? Möchten Sie Symlinks auch rekursiv auflösen? (Wenn / bar selbst ein Symlink ist, möchten Sie ihm folgen?)
200_success

Antworten:

7

In zsh gibt es dafür einen Modifikator oder vielmehr zwei: Asymbolische Verknüpfungen (mit realpath ) aufzulösen und hden „Kopf“ (dh den dirname) zu extrahieren .

cd $file(:A:h)

Dies funktioniert nur, wenn die Symbolik nicht gebrochen ist. Wenn es eine Kette symbolischer Glieder gibt, wird diese bis zum endgültigen Ziel verfolgt. Wenn das Verzeichnis über einen symbolischen Link erreicht wurde, befinden Sie sich im Ziel (wie bei cd -P).


Ohne zsh, wenn Sie das readlinkDienstprogramm haben und in das Verzeichnis wechseln möchten, das das Ziel des symbolischen Links enthält:

cd -- "$(dirname -- "$(readlink -- "$file")")"

Das Ziel des Links könnte selbst ein Symlink sein. Wenn Sie in das Verzeichnis wechseln möchten, das das endgültige Ziel des Links enthält, können Sie readlinkin einer Schleife Folgendes aufrufen :

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

Unter Linux können Sie readlink -fden Pfad kanonisieren, sofern der Symlink nicht unterbrochen ist :

t=$(readlink -f -- "$file")
cd "${t%/*}"
Gilles 'SO - hör auf böse zu sein'
quelle
Hervorragende Antwort: cd $file(:A:h)ist genau das, wonach ich gesucht habe!
Chauncey Garrett
7

Sie können readlinkden symbolischen Link auflösen und dann dirnamesein Verzeichnis abrufen.

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$ 
Kevin
quelle
1
Hinweis: Dies ist ein perfektes Beispiel dafür, warum $()anstelle von Backticks verwendet wird.
Kevin
0

eine Linie:

cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))
DIYismus
quelle
Dies ist Ihre zweite einzeilige Antwort (es scheint sogar genau dieselbe Antwort zu sein). Auch hier sind einzeilige Antworten nicht besonders hilfreich. Bitte erweitern Sie Ihre Antworten um weitere hilfreiche Informationen und Erklärungen (einschließlich unterstützender Links und Dokumentationen).
HalosGhost