Besser spät als nie, nehme ich an. Ich war motiviert, dies zu entwickeln, weil meine Fedora-Skripte auf dem Mac nicht funktionierten. Das Problem sind Abhängigkeiten und Bash. Macs haben sie nicht, oder wenn sie sie haben, sind sie oft irgendwo anders (ein anderer Pfad). Die Manipulation von Abhängigkeitspfaden in einem plattformübergreifenden Bash-Skript bereitet bestenfalls Kopfzerbrechen und stellt schlimmstenfalls ein Sicherheitsrisiko dar - daher ist es am besten, ihre Verwendung zu vermeiden, wenn dies möglich ist.
Die unten stehende Funktion get_realpath() ist einfach, Bash-zentriert und es sind keine Abhängigkeiten erforderlich. Ich verwende nur die Bash-Builtins echo y cd . Es ist auch ziemlich sicher, da alles auf jeder Stufe des Weges getestet wird und es Fehlerbedingungen zurückgibt.
Wenn Sie den Symlinks nicht folgen wollen, dann setzen Sie setzen -P am Anfang des Skripts, aber ansonsten cd sollte die Symlinks standardmäßig auflösen. Es wurde mit Dateiargumenten getestet, die {absolut | relativ | Symlink | lokal} sind, und es gibt den absoluten Pfad zur Datei zurück. Bisher hatten wir keine Probleme damit.
function get_realpath() {
if [[ -f "$1" ]]
then
# file *must* exist
if cd "$(echo "${1%/*}")" &>/dev/null
then
# file *may* not be local
# exception is ./file.ext
# try 'cd .; cd -;' *works!*
local tmppwd="$PWD"
cd - &>/dev/null
else
# file *must* be local
local tmppwd="$PWD"
fi
else
# file *cannot* exist
return 1 # failure
fi
# reassemble realpath
echo "$tmppwd"/"${1##*/}"
return 0 # success
}
Sie können diese Funktion mit anderen Funktionen wie get_dirname, get_filename, get_stemname und validate_path kombinieren. Diese können in unserem GitHub-Repository gefunden werden als realpath-lib (Um es ganz offen zu sagen - dies ist unser Produkt, aber wir bieten es der Gemeinschaft kostenlos und ohne jegliche Einschränkungen an). Es könnte auch als Lehrmittel dienen - es ist gut dokumentiert.
Wir haben unser Bestes getan, um so genannte "moderne Bash"-Praktiken anzuwenden, aber Bash ist ein großes Thema und ich bin sicher, dass es immer Raum für Verbesserungen geben wird. Es erfordert Bash 4+, könnte aber auch mit älteren Versionen funktionieren, falls diese noch verfügbar sind.
1 Stimmen
Etwas spät, aber in Ihrer Frage fehlt ein Hinweis auf die von Ihnen verwendete Shell. Dies ist wichtig, denn
readlink
kann ein eingebauter oder ein externer Befehl sein.1 Stimmen
Das würde vielleicht den Unterschied erklären. Ich bin mir aber ziemlich sicher, dass ich bei beiden Gelegenheiten die Bash verwendet habe.
3 Stimmen
Warum ist diese Option auf Macs verboten?
0 Stimmen
@CommaToast - wenn ich mich recht erinnere, versuchen die Macs beim "Unix"-Teil des Betriebssystems, sich an POSIX- und/oder BSD-abgeleitete Tools und Dienstprogramme zu halten. Sie können GNU-Dienstprogramme auf OS/X installieren oder die Befehle so anpassen, dass sie eine "reine" Bourne-Shell verwenden (
/bin/sh
ohnebash
Erweiterungen). Für viele Entwickler sind heutzutage Shell-Skripte = Linux, GNU-Utilities undbash
so dass Probleme der Übertragbarkeit auftreten.5 Stimmen
Ich wünschte wirklich, Apple würde OS X dazu bringen, mehr Standard-Linux-Pfade zu unterstützen und sich um solche Dinge zu kümmern. Sie könnten es tun, ohne irgendetwas kaputt zu machen, oder?
1 Stimmen
@CommaToast Nun, sie werden mit Perl ausgeliefert, also ++ :-) ... öffnen Sie Terminal.app und geben Sie ein:
touch myfile ; ln -s myfile otherfile ; perl -MCwd=abs_path -le 'print abs_path readlink(shift);' otherfile
... in meinem Fall sehe ich: /Users/cito/myfile`. Ich habe es zu meiner Antwort unten hinzugefügt. Zum Wohl.1 Stimmen
@CommaToast GNU ist nicht Unix :-) Es wurde etwas hinzugefügt. Sie können eine Lösung mit
pwd -P
unter OS X, ohne etwas zu installieren1 Stimmen
@CommaToast
readlink
ist GPLv3 und Apple wird nichts anrühren, was unter der GPLv3 steht, da es erforderlich ist, einem Gerät kryptografische Schlüssel zu übergeben, um GPLv3-Software auf diesem Gerät zu ändern. gnu.org/licenses/ Das wird ein Grund dafür sein, dass die Standard-Shell nicht mehr Bash, sondern Zsh ist1 Stimmen
@JasonS aber FreeBSD hatte
readlink -f
seit irgendwann zwischen 2010 und 2012 abhängig vom Datum der Manpage und dem Datum der BSD-Veröffentlichung, und das ist keine GPL-Implementierung. Apple zögert also nur. Und tatsächlich,readlink -f
hat seinen Ursprung in OpenBSD 2.1 im Jahr 1997, soweit ich das beurteilen kann. Die erste Implementierung war also nicht einmal GNU. Ich kann verstehen, dass es nicht in Snow Leopard ist, aber ich kann nicht verstehen, dass es nicht in Mavericks/Sierra ist.0 Stimmen
@WyattWard Gutes Argument. Der einzige Mac, zu dem ich Zugang habe (10.11 Big Sur), hat das Datum des Readlinks von 2003. Also ja, es könnte aktualisiert werden. Und wie du sagst, nicht GPLv3 überhaupt, so ignorieren Sie meine früheren Kommentar über es GPLv3. Ich war ein bisschen blind, weil sich so viele Leute darüber beschwert haben, dass Mac OS nicht GNU ist. Nein, ist es nicht. Wird es auch nie sein. Aber der Punkt bleibt, dass man die Arbeit trotzdem erledigen kann mit
pwd -P
ohne zu wünschen, dass Mac OS ein GNU Linux ist, indem man Homebrew benutzt. Ja, Shell-Skripte sind nicht portabel. Das gilt nicht nur für Mac OS.4 Stimmen
MacOS 12.3 unterstützt
readlink -f
.