Wie bekomme ich den vollständigen Pfad einer Datei in Bash?

21

Ich möchte einen einfachen Weg, um den vollständigen Pfad zu einer Datei zu erhalten. Ich schreibe gerade folgendes:

echo `pwd`/file.ext

Beim Versuch, es zu verkürzen, habe ich einen Bash-Alias ​​erstellt:

alias fp='echo `pwd`/'

Aber jetzt, wenn ich tippe fp file.ext, erscheint ein Leerzeichen zwischen dem /und dem file.ext.

Gibt es einen solchen Befehl schon und ich vermisse ihn? Wenn nicht, wie würde ich vorgehen, um einen solchen Alias ​​oder eine solche Funktion in Bash zu erstellen?

Jens Erat
quelle

Antworten:

29

Auf Linux-Systemen sollten Sie readlinkdas GNU-Coreutils-Projekt installiert haben und können dies tun:

readlink -f file.ext

Auf Debian / Ubuntu-Systemen ist möglicherweise das Dienstprogramm " realpath" installiert, das " im Wesentlichen die gleiche Funktionalität wie /bin/readlink -fim Paket" coreutils "bietet .

Doug Harris
quelle
readlink -f(oder realpath, ein älteres Dienstprogramm, das aus Kompatibilitätsgründen beibehalten wird) erweitert zusätzlich alle symbolischen Links, was nicht unbedingt wünschenswert ist.
Gilles 'SO- hör auf böse zu sein'
8
Zu Ihrer Information: Funktioniert nicht auf MacOSX.
Akira
Auf meinem Mac habe ich Coreutils mit Homebrew installiert und es enthält realpath.
Doug Harris
7

pwdVerwenden PWDSie anstelle des Befehls die Variable (auch in POSIX):

fp () {
  case "$1" in
    /*) printf '%s\n' "$1";;
    *) printf '%s\n' "$PWD/$1";;
  esac
}

Wenn Sie Windows unterstützen müssen, wird das Erkennen absoluter Pfade komplizierter, da jeder Port von Unix-Tools seine eigenen Regeln für die Übersetzung von Dateipfaden hat. Verwenden Sie bei Cygwin das cygpathDienstprogramm.

Gilles 'SO - hör auf böse zu sein'
quelle
Möglicherweise haben Sie die Wahl, aber diese Funktion gibt die neue Zeile nicht aus.
CYRUS
Dieser Ansatz hat den Vorteil, dass nur Shell-Builtins verwendet werden, was schneller ist, als externe Binärdateien aufzurufen. Sie sollten diese Tatsache ein wenig klarer machen.
Akira
4

Um Ihre Frage mit dem zu beantworten, was Sie gerade verwenden:

Der Alias ​​wird an der Stelle erweitert, an der Sie gerade tippen. Sie tippten:

% fp<SPACE>file.ext

das wird

% echo `pwd`<SPACE>file.exe

Sie könnten eine Funktion verwenden, um dies zu vermeiden:

function fp() {
    echo `pwd`/"$1"
}

Sie können das wie gewohnt verwenden:

% fp file.ext
Akira
quelle
Sie brauchen doppelte Anführungszeichen um Variablen- und Befehlsersetzungen:echo "`pwd`/$1"
Gilles 'SO - hören Sie auf, böse zu sein'
@ Gilles: unter welchen Umständen?
Akira
2
@akira: Verwenden Sie immer doppelte Anführungszeichen, es sei denn, Sie möchten, dass das Ergebnis der Erweiterung als Globbing-Muster behandelt und das Ergebnis des Globbing in Wörter aufgeteilt wird. Hier erstellen Sie einen einzelnen Dateinamen, sodass doppelte Anführungszeichen erforderlich sind (testen Sie Ihre Funktion mit einer Datei, die *in einem Verzeichnis aufgerufen wird, das andere Dateien enthält).
Gilles 'SO - hör auf böse zu sein'
Das ' ' wird von der Shell globalisiert (zsh in meinem Fall) und erweitert, bevor sie die Funktion ausführen. fp *ergibt, /tmp/4cc3ea0c1b34bda dies der erste Parameter für die Funktion ist. Die anderen Parameter sind die anderen Dateien im Verzeichnis. sobald ich eine datei mit dem
namen
bash ist die "schlechte" hier, wie es scheint, bash ergibt, worauf Sie sich beziehen.
Akira
3

Sie können verwenden:

realpath file.ext
cYrus
quelle
Ich habe das nicht. Woher kommt das?
Frabjous
@frabjous: Es ist spezifisch für Debian und Derivate und wird nur installiert, wenn Sie es angefordert haben oder ein Paket, das davon abhängt.
Gilles 'SO- hör auf böse zu sein'
Ich benutze Arch. Das ist nicht Debian-basiert, aber es gibt ein Paket dafür in der AUR. Ich bin mir nicht sicher, ob es sich lohnt, einen Readlink zu installieren.
Frabjous
Nun, das ist eine Option. oder Sie können eine Funktion in Betracht ziehen, siehe Gilles Antwort. Wie auch immer, das hängt von der tatsächlichen Verwendung ab, die Sie damit machen möchten (ich bin neugierig).
CYRUS
@frabjous: Sie haben nicht angegeben, auf welchem ​​System Sie sich befinden, aber wenn es einen Aptitude-basierten Paketmanager (Debian, Ubuntu, Mint usw.) verwendet, können Sie eingeben , um zu verdeutlichenapt-cache search realpath , dass die Coreutils und einfachen alten Realpath- Pakete vorhanden sind beide enthalten es. Sie können dann sudo apt-get install realpath(oder coreutils) eingeben, um es zu installieren.
Michael Scheper
1

Von /programming//a/3915420/5795941

Dies ist der einzige Weg, der für mich akzeptabel ist. Erweitert keine Links wie Realpath und Readlink und ist die klassische Methode, die ich überall gesehen habe.

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"
Philippe Carphin
quelle