Frage: Gibt es einen einfachen Befehl sh / bash / zsh / fish / ..., um den absoluten Pfad der Datei zu drucken, die ich füttere?
Anwendungsfall: Ich bin im Verzeichnis /a/b
und möchte den vollständigen Pfad zur Datei c
in der Befehlszeile drucken , damit ich ihn einfach in ein anderes Programm einfügen kann : /a/b/c
. Ein einfaches, aber ein kleines Programm, um dies zu tun, könnte mir wahrscheinlich 5 oder so Sekunden sparen, wenn es darum geht, lange Pfade zu bewältigen, was sich letztendlich summiert. Es überrascht mich also, dass ich kein Standarddienstprogramm dafür finden kann - gibt es wirklich keines?
Hier ist eine Beispielimplementierung, abspath.py:
#!/usr/bin/python
# Author: Diggory Hardy <[email protected]>
# Licence: public domain
# Purpose: print the absolute path of all input paths
import sys
import os.path
if len(sys.argv)>1:
for i in range(1,len(sys.argv)):
print os.path.abspath( sys.argv[i] )
sys.exit(0)
else:
print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
sys.exit(1)
Antworten:
Versuchen Sie es
realpath
.quelle
realpath
: github.com/westonruter/misc-cli-tools/blob/master/realpathVersuchen Sie,
readlink
welche symbolischen Links aufgelöst werden:quelle
-m
die beste Option ist./usr/bin/readlink
auf Mavericks. Oder meinten Sie, dass diese Optionen unter OS X nicht gefunden werden? Es scheint eine verkümmerte BSD-Version zu sein ...: preadlink
Manpage :only the target of the symbolic link is printed. If the given argument is not a symbolic link, readlink will print nothing and exit with an error
, daher funktioniert Readlink für diesen Zweck unter OSX nichtquelle
a b
(zwei Leerzeichen zwischen a und b, SO isst eines davon).function realpath { echo $(cd $(dirname $1); pwd)/$(basename $1); }
mir unterrealpath
OS X einen Befehl (derzeit akzeptierte Antwort) gemacht. Danke!LOG=$(echo $(cd $(dirname $0); pwd)/$(basename $0 .sh).log)
Vergessen Sie
readlink
undrealpath
die auf Ihrem System sein oder kann nicht installiert werden.Die Antwort von dogbane oben wird hier als Funktion ausgedrückt:
Sie können es dann folgendermaßen verwenden:
Wie und warum funktioniert es?
Die Lösung nutzt die Tatsache aus, dass der integrierte
pwd
Befehl Bash den absoluten Pfad des aktuellen Verzeichnisses druckt, wenn er ohne Argumente aufgerufen wird.Warum mag ich diese Lösung?
Es ist portabel und erfordert weder eines
readlink
noch das,realpath
was bei einer Standardinstallation einer bestimmten Linux / Unix-Distribution häufig nicht vorhanden ist.Was ist, wenn dir nicht existiert?
Wie oben angegeben, schlägt die Funktion fehl und wird auf stderr gedruckt, wenn der angegebene Verzeichnispfad nicht vorhanden ist. Dies ist möglicherweise nicht das, was Sie wollen. Sie können die Funktion erweitern, um diese Situation zu behandeln:
Jetzt wird eine leere Zeichenfolge zurückgegeben, wenn eines der übergeordneten Verzeichnisse nicht vorhanden ist.
Wie gehst du mit '..' oder '.' in Eingabe?
Nun, es gibt in diesem Fall einen absoluten Pfad, aber keinen minimalen. Es wird so aussehen:
Wenn Sie das '..' auflösen möchten, müssen Sie das Skript wie folgt erstellen:
quelle
realpath
aus coreutils Paket kommt, die auch enthält Tools wiewho
,touch
odercat
. Es handelt sich um eine ziemlich standardmäßige Reihe von GNU-Tools, sodass Sie ziemlich sicher sein können, dass diese auf fast jedem Linux-basierten Computer installiert ist. Sie haben jedoch Recht: Es gibt zwei Probleme: i) Sie werden sie wahrscheinlich bei der Standardinstallation auf vermissen Nicht-GNU-Unix-Systeme (wie OpenBSD) ii) Dieses Tool wurde in Version 8.15 eingeführt (es ist also ab 2012 ziemlich neu), sodass Sie es auf langfristig stabilen Systemen (wie RHEL 6) vermissen werden.Dies ist besser als
readlink -e FILE
oderrealpath
, da es auch dann funktioniert, wenn die Datei nicht vorhanden ist.quelle
-m
Option ist bei Mavericks nicht verfügbar.Dieser relative Pfad zur absoluten Pfadkonverter- Shell-Funktion
cd
undpwd
)..
und.
Code:
Stichprobe:
Hinweis: Dies basiert auf den Antworten von nolan6000 und bsingh , behebt jedoch den Dateifall .
Ich verstehe auch, dass die ursprüngliche Frage ein vorhandenes Befehlszeilenprogramm betraf. Aber da dies DIE Frage zum Stackoverflow zu sein scheint, einschließlich Shell-Skripten, die minimale Abhängigkeiten aufweisen möchten, habe ich diese Skriptlösung hier eingefügt, damit ich sie später finden kann :)
quelle
$ abspath 'a b c/file.txt'
Das Argument zucd
wird nicht in Anführungszeichen gesetzt. Um dies zu überwinden, zitieren Sie anstelle des gesamten Argumentsecho
(gibt es einen Grund für diese Anführungszeichen?) Nur die Pfadargumente. Dh ersetzenecho "$(cd ${1%/*}; pwd)/${1##*/}"
durchecho $(cd "${1%/*}"; pwd)/${1##*/}
.echo "$(cd "$1"; pwd)"
mit(cd "$1"; pwd)
. Hier besteht keine Notwendigkeit für Echo.( ... )
werden weiterhin benötigt, so dasscd
dies in einer Subshell geschieht, da wir das Arbeitsverzeichnis für keine Anrufer von ändern möchtenabspath
.Der
find
Befehl kann helfenListet alle Dateien im oder unter dem aktuellen Verzeichnis mit Namen auf, die dem Muster entsprechen. Sie können es vereinfachen, wenn Sie nur wenige Ergebnisse erhalten (z. B. Verzeichnis am unteren Rand des Baums mit wenigen Dateien)
Ich verwende dies unter Solaris 10, das nicht über die anderen genannten Dienstprogramme verfügt.
quelle
PWD
, können Sie einfach verwenden$PWD/$filename
.Wenn Sie keine Readlink- oder Realpath-Dienstprogramme haben, können Sie die folgende Funktion verwenden, die in bash und zsh funktioniert (über den Rest nicht sicher).
Dies funktioniert auch für nicht vorhandene Dateien (ebenso wie die Python-Funktion
os.path.abspath
).Leider werden
abspath ./../somefile
die Punkte nicht los.quelle
echo "$1"
durchprintf "%s\n" "$1"
(dasselbe mit dem zweiten Echo).echo
kann Backslashes in seinen Argumenten interpretieren.Hier ist eine Nur-Zsh-Funktion, die ich wegen ihrer Kompaktheit mag. Es wird der Erweiterungsmodifikator 'A' verwendet - siehe zshexpn (1).
quelle
Es ist in der Regel nicht so etwas wie die
absolute path
in eine Datei (diese Aussage bedeutet , dass es im Allgemeinen mehr sein kann als ein, daher die Verwendung des bestimmten Artikels der nicht geeignet ist). Anabsolute path
ist ein beliebiger Pfad, der vom Stammverzeichnis "/" ausgeht und eine Datei ohne Mehrdeutigkeit unabhängig vom Arbeitsverzeichnis bezeichnet (siehe z. B. Wikipedia ).A
relative path
ist ein Pfad, der ausgehend von einem anderen Verzeichnis interpretiert werden soll. Es kann das Arbeitsverzeichnis sein, wenn esrelative path
von einer Anwendung manipuliert wird (wenn auch nicht unbedingt). Wenn es sich in einem symbolischen Link in einem Verzeichnis befindet, soll es im Allgemeinen relativ zu diesem Verzeichnis sein (obwohl der Benutzer möglicherweise andere Verwendungszwecke hat).Daher ist ein absoluter Pfad nur ein Pfad relativ zum Stammverzeichnis.
Ein Pfad (absolut oder relativ) kann symbolische Verknüpfungen enthalten oder nicht. Wenn dies nicht der Fall ist, ist es auch etwas undurchlässig für Änderungen in der Verknüpfungsstruktur, aber dies ist nicht unbedingt erforderlich oder sogar wünschenswert. Einige Leute nennen
canonical path
(odercanonical file name
oderresolved path
) eine,absolute path
in der alle symbolischen Verknüpfungen aufgelöst wurden, dh durch einen Pfad ersetzt wurden, zu dem sie verknüpfen. Die Befehlerealpath
undreadlink
beide suchen nach einem kanonischen Pfad, haben jedoch nurrealpath
die Option, einen absoluten Pfad abzurufen, ohne sich die Mühe zu machen, symbolische Links aufzulösen (zusammen mit mehreren anderen Optionen, um verschiedene Arten von Pfaden abzurufen, absolut oder relativ zu einem Verzeichnis).Dies erfordert mehrere Bemerkungen:
realpath
undreadlink
haben Optionen, um dies zu berücksichtigen.canonical
. Daher ist das Konzept zeit- (oder umwelt-) abhängig.canonical path
eine Datei aus zwei Gründen immer noch mehrere enthalten :ro
) an mehreren Einhängepunkten bereitgestellt.Selbst mit der viel restriktiveren Definition von
canonical path
kann es daher mehrere kanonische Pfade zu einer Datei geben. Dies bedeutet auch, dass das Qualifikationsmerkmalcanonical
etwas unzureichend ist, da es normalerweise einen Begriff der Einzigartigkeit impliziert.Dies erweitert eine kurze Diskussion des Themas in einer Antwort auf eine andere ähnliche Frage bei Bash: Abrufen des absoluten Pfades, der relativ angegeben ist
Mein Fazit ist, dass
realpath
es besser gestaltet und viel flexibler ist alsreadlink
. Die einzige Verwendungreadlink
, die nicht abgedecktrealpath
ist, ist der Aufruf ohne Option, der den Wert einer symbolischen Verknüpfung zurückgibt.quelle
realpath
vsreadlink
oder sogar zu symbolischen Links überschüssig zu dem, was ich gefragt habe.canonical
bezieht sich genau auf diese Einzigartigkeit in Bezug auf eine Reihe von Transformationen. Aber zum Beispiel ist / dev / cdrom ein vollkommen guter absoluter Pfad, obwohl es tatsächlich eine Verbindung zu / dev / sr0 ist. Beide zeigen auf dasselbe Gerät. Meine ursprüngliche Antwort zeigte auf einen relevanten Webartikel.Die
dogbane
Antwort mit der Beschreibung, was kommt:Erläuterung:
"$1"
dirname "$1"
cd "$(dirname "$1")
in dieses relative Verzeichnis und erhalten den absoluten Pfad dafür, indem wir denpwd
Shell-Befehl ausführen$(basename "$1")
echo
es geschafftquelle
Denn Verzeichnisse werden
dirname
ausgelöst../
und zurückgegeben./
.Die Funktion von nolan6000 kann geändert werden, um Folgendes zu beheben:
quelle
.profile
und steht somit für die interaktive Verwendung zur Verfügung.$1
es sich um einen einfachen Dateinamen handelt:get_abs_filename foo
-> nichts (oder<current_dir>/foo/foo
wennfoo
es sich um ein Verzeichnis handelt).Dies ist keine Antwort auf die Frage, sondern für diejenigen, die Skripte erstellen:
es behandelt / .. ./ etc richtig. Ich scheine auch an OSX zu arbeiten
quelle
Ich habe das folgende Skript auf meinem System platziert und nenne es einen Bash-Alias, wenn ich schnell den vollständigen Pfad zu einer Datei im aktuellen Verzeichnis abrufen möchte:
Ich bin nicht sicher warum, aber unter OS X erweitert sich "$ PWD" auf den absoluten Pfad, wenn es von einem Skript aufgerufen wird. Wenn der Befehl find in der Befehlszeile aufgerufen wird, ist dies nicht der Fall. Aber es macht was ich will ... genießen.
quelle
$PWD
hat immer den absoluten Pfad des Arbeitsverzeichnisses. Außerdemfind
werden keine Schrägstriche toleriert, sodass Sie die gestellte Frage nicht beantworten. Ein schnellerer Weg, um das zu tun, wonach Sie suchen, wäre einfachecho "$PWD/$1"
Das einfachste, wenn Sie nur integrierte Funktionen verwenden möchten, ist wahrscheinlich:
Es müssen nur zwei zusätzliche Wörter eingegeben werden. Dies funktioniert auf allen Unix-Systemen sowie unter OSX.
quelle
-maxdepth 1
vorher hinzufügen-name
(vorausgesetzt, die Datei befindet sich im aktuellen Verzeichnis). Ohne das funktioniert es mit Dateien in jedem Unterverzeichnis von pwd, aber nicht mit anderen.find
werde keine Datei außerhalb des Verzeichnisbaums darunter findenpwd
. Wenn Sie es beispielsweise versuchenfind . -name ../existingFile
, schlägt dies fehl.Dies gleicht die Mängel aus
realpath
, es in einem Shell-Skript zu speichernfullpath
. Sie können jetzt anrufen:quelle
realpath "foo bar"
->/home/myname/foo bar
. Wenn Sie nicht die Mühe haben, Befehlszeilenargumente zu zitieren, ist dies nichtrealpath
die Schuld.Eine Alternative, um den absoluten Pfad in Ruby zu ermitteln :
realpath() {ruby -e "require 'Pathname'; puts Pathname.new('$1').realpath.to_s";}
Funktioniert ohne Argumente (aktueller Ordner) und relativen und absoluten Datei- oder Ordnerpfad als Dokument.
quelle
Antworte mit Homebrew
realpath
ist die beste Antwort, aber wenn Sie es nicht installiert haben, müssen Sie zuerst ausführenbrew install coreutils
, um Coreutils mit vielen fantastischen Funktionen zu installieren . Das Schreiben und Exportieren einer benutzerdefinierten Funktion ist zu viel Arbeit und Fehlerrisiko für so etwas. Hier sind zwei Zeilen:quelle
Hey Leute, ich weiß, dass es ein alter Thread ist, aber ich poste dies nur als Referenz für alle anderen, die dies wie ich besucht haben. Wenn ich die Frage richtig verstanden habe, denke ich den
locate $filename
Befehl. Es zeigt den absoluten Pfad der angegebenen Datei an, jedoch nur, wenn er vorhanden ist.quelle
locate
ist ein Dienstprogramm zum Suchen nach Dateien / Pfaden nach Namen. Es kann den Job erledigen, aber auch andere Übereinstimmungen finden und möglicherweise keine vorhandene Datei finden, ohne zuerstupdatedb
als root aufzurufen .