Dies ist eine zusätzliche Frage, die mit dieser begann: Wie bearbeitet man symbolische Links in OS X?
Jetzt, da ich weiß, wie man den Pfad bearbeitet, auf den Symlinks verweisen, versuche ich herauszufinden, wie man das rekursiv für jeden defekten Symlink macht. Ich bin ein PHP-Typ, daher ist mir dieses CLI-Zeug etwas fremd ...
Es scheint einige spezifische Elemente dafür zu geben, nämlich:
Das erste ist ziemlich einfach:
find /path/to/search -type l | while read f; do if [ ! -e "$f" ]; then ls -l "$f"; fi; done
Dadurch bekomme ich eine schöne Liste aller defekten Symlinks, die unterhalb des bereitgestellten Verzeichnisses gefunden wurden. Aber ich glaube, ich müsste die Position von jedem in einer Variablen (Array?) Speichern, um damit zu arbeiten.
Als nächstes scheint es, dass das Ändern der Aktion, die im "dann"-Teil der Logik bereitgestellt wird, die Lösung liefern würde.
Artikel 2 kann abgerufen werden mit:
readlink /path/to/broken/symlink
Es scheint also, dass wir das in eine Variable schieben müssen. Mir ist unklar, wie ich das im Terminal machen soll.
Nummer 3 wäre eine einfache Bearbeitung des in Schritt 2 abgerufenen Pfads. Ich muss den alten Laufwerksnamen durch den neuen ersetzen. Also ändern:
/Volumes/Old\ Drive/path/to/symlink
Zu
/Volumes/New\ Drive/path/to/symlink
Es ist auch unklar, wie genau dies in einem CLI-Skript zu tun ist. Eine Art Saitenersatz scheint erforderlich zu sein. So etwas wie str_replace in der PHP-Welt.
Schließlich kann Schritt 4 durchgeführt werden über:
ln -f -s /path/to/new/location/of/original /path/to/location/of/broken/symlink/
wie in meiner anderen Frage beschrieben, die zuvor oben verlinkt wurde.
Wie genau würde ich diese Konzepte aneinanderreihen, um das gewünschte Ergebnis zu erzielen, alle meine Symlinks auf einen Schlag zu reparieren?
Aus dem Kopf (und ohne jegliche Tests):
Erstellen Sie eine Textdatei mit folgendem Inhalt
#!/bin/bash
find "$1" -type l | while read symlink; do
if [ ! -e "$symlink" ]; then
old_path=$(readlink "$symlink")
new_path=${old_path/Old Drive/New Drive}
ln -f -s "$new_path" "$symlink"
fi
done
Machen Sie es ausführbar, indem Sie es ausführenchmod +x name-of-file
./name-of-file /path/to/search
Dies ist ungetestet , also versuchen Sie es zuerst mit einem Beispielverzeichnis.
Um einige Erklärungen hinzuzufügen
old_path=$(readlink "$symlink")
führt den Befehl aus $(...)
und weist das Ergebnis zu$old_path
${old_path/Old Drive/New Drive}
macht Textersetzung an$old_path
Um in einer bash
Shell eine Variable zu setzen, verwenden Sie einfach set NAME=bob
oder set VITAL_SIGNS=none
.
Sie können eine Variable auch mithilfe der Ausgabe eines Befehls festlegen, indem Sie die bash
Funktion -builtin aufrufen read
, um die Ausgabe einer benannten Variablen zuzuweisen. Dies funktioniert gut in einem Pipestream wie folgt:
ls -l | wc -l | read NUMBER_OF_LINES
Oder Sie können die Ausgabe direkt einer Variablen zuweisen:
LICENSE_KEY=$(cat ~/software/key.txt | grep KEY | awk '{print $1}')
Eine gute Möglichkeit, Variablen rekursiv zu lesen, ist in einer Schleife wie folgt:
for BROKEN_LINK in $(commands to produce a list of files)
do
commands here to sort your links out, noting that the broken links are stored in the variable $BROKEN_LINKS
done
In Anbetracht des oben Gesagten sollte so etwas wie das Folgende funktionieren:
beweisen, dass ein Ordner nicht existiert
StuffeMac:dan stuffe$ ls ~/Desktop/broken_links
ls: /Users/stuffe/Desktop/broken_links: No such file or directory
beweisen, dass ein neuer Zielordner existiert
StuffeMac:dan stuffe$ ls ~/Desktop/working_links
StuffeMac:dan stuffe$
Erstellen Sie einige ungültige und gültige Links
StuffeMac:dan stuffe$ ln -s ~/Desktop/brokenlinks/dan1
StuffeMac:dan stuffe$ ln -s ~/Desktop/brokenlinks/dan2
StuffeMac:dan stuffe$ ln -s ~/Desktop/working_links/dan3
StuffeMac:dan stuffe$ ln -s ~/Desktop/outofscopedeadlinks/dan4
StuffeMac:dan stuffe$ ls -l
total 32
lrwxr-xr-x 1 stuffe staff 38 8 Dec 10:06 dan1 -> /Users/stuffe/Desktop/brokenlinks/dan1
lrwxr-xr-x 1 stuffe staff 38 8 Dec 10:06 dan2 -> /Users/stuffe/Desktop/brokenlinks/dan2
lrwxr-xr-x 1 stuffe staff 40 8 Dec 10:06 dan3 -> /Users/stuffe/Desktop/working_links/dan3
lrwxr-xr-x 1 stuffe staff 46 8 Dec 10:21 dan4 -> /Users/stuffe/Desktop/outofscopedeadlinks/dan4
Holen Sie sich eine Liste toter Links in eine Datei zur Eingabe
StuffeMac:dan stuffe$ find . -type l | while read f; do if [ ! -e "$f" ]; then ls "$f" >> deadlinks.txt; fi; done
StuffeMac:dan stuffe$ more deadlinks.txt
./dan1
./dan2
./dan4
Führen Sie eine Schleife gegen jeden toten Link aus
StuffeMac:dan stuffe$ for DEAD_LINK in $(cat deadlinks.txt)
> do
> DESTINATION_IN_SCOPE=$(readlink $DEAD_LINK | grep brokenlinks | wc -l)
> NEW_DESTINATION="~/Desktop/working_links/"
> if [ $DESTINATION_IN_SCOPE = "1" ]
> then
> NEW_LINK=$(echo $DEAD_LINK | colrm 1 2)
> ln -f -s $NEW_DESTINATION$NEW_LINK $DEAD_LINK
> else
> echo "Link $DEAD_LINK not in target folder"
> fi
> done
Link ./dan4 not in target folder
StuffeMac:dan stuffe$
Überprüfen Sie die symbolischen Links nach den Änderungen
StuffeMac:dan stuffe$ ls -l
total 32
lrwxr-xr-x 1 stuffe staff 28 8 Dec 10:08 dan1 -> ~/Desktop/working_links/dan1
lrwxr-xr-x 1 stuffe staff 28 8 Dec 10:08 dan2 -> ~/Desktop/working_links/dan2
lrwxr-xr-x 1 stuffe staff 40 8 Dec 10:06 dan3 -> /Users/stuffe/Desktop/working_links/dan3
lrwxr-xr-x 1 stuffe staff 46 8 Dec 10:21 dan4 -> /Users/stuffe/Desktop/outofscopedeadlinks/dan4
bash
Art, die Ausgabe von Befehlen zu erfassen, besteht darin, die $(command)
Syntax wie zu verwenden for MYVAR in $(ls | grep somefilter)
, anstatt Backticks zu verwenden. Es hat einige Vorteile gegenüber Backticks wie diesem . Ich habe auf dieser Grundlage Änderungen vorgenommen.
JVC
Run: Command not found
kein Hang
Jan C.
bash
Syntax gelernt. Also ein Upvote dafür! Danke!JVC
kein Hang
new_path=
Zeile. Wenn Sie ein echtes Beispiel Ihres alten und neuen Pfads hinzufügen, kann ich das Skript entsprechend anpassen.JVC
JVC