Befehl realpath nicht gefunden

24

Ich habe Debian Squeeze AMD64. Meine aktuelle Shell ist Bash. Wenn ich Folgendes in mein Terminal schreibe, funktioniert es:

$ uname -a
Linux core 2.6.32-5-amd64 #1 SMP Fri May 10 08:43:19 UTC 2013 x86_64 GNU/Linux
$ echo $SHELL
/bin/bash                                                                                                                                                                                     
$ echo $(realpath test.sh)                                                                                                                                                     
/home/ffortier/test.sh

Meine test.sh-Datei sieht folgendermaßen aus:

#!/bin/bash
echo $(realpath "$1")

Wenn ich versuche, Folgendes auszuführen, erhalte ich eine Fehlermeldung

$ ./test.sh test.sh 
./test.sh: line 2: realpath: command not found

Wie kann ich den Befehl realpath in einer Bash-Datei verwenden?

zusätzliche Information

$ type -a realpath
realpath is a function                                                                                                                                                                        
realpath ()                                                                                                                                                                                   
{                                                                                                                                                                                             
    f=$@;                                                                                                                                                                                     
    if [ -d "$f" ]; then                                                                                                                                                                      
        base="";                                                                                                                                                                              
        dir="$f";                                                                                                                                                                             
    else                                                                                                                                                                                      
        base="/$(basename "$f")";                                                                                                                                                             
        dir=$(dirname "$f");                                                                                                                                                                  
    fi;                                                                                                                                                                                       
    dir=$(cd "$dir" && /bin/pwd);                                                                                                                                                             
    echo "$dir$base"                                                                                                                                                                          
}           
Francis
quelle

Antworten:

9

Ist realpath ein tatsächlicher Befehl oder ein Skript? Ich würde nachsehen, woher es kommt.

$ type -a realpath

Ich bin mit diesem Tool nicht vertraut und daher ist es wahrscheinlich nicht Teil Ihrer normalen Distribution. Vielleicht ist es an einem nicht standardmäßigen Ort installiert, der nicht auf Bashs vorhanden ist, $PATHsondern sich in Ihrer Anmeldeumgebung befindet $PATH.

In jedem Fall typezeigt Ihnen der obige Befehl, woher der Befehl kommt. An diesem Punkt können Sie die Methode, die Sie in Ihrem Skript aufrufen, folgendermaßen ändern:

echo $(/path/to/realpath test.sh)

Oder ändern Sie Ihre Skripts $PATHso, dass sie auch diesen nicht standardmäßigen Speicherort enthalten.

Funktionen in der Shell

Ein Großteil Ihrer Umgebung wird nicht aufgerufen, wenn Sie ein Shell-Skript aufrufen. Wenn Sie darüber nachdenken, ist dies sehr sinnvoll, da Skripte im Allgemeinen nicht das gesamte zusätzliche Gepäck haben sollen, das die Umgebung eines Benutzers möglicherweise hat.

Sie können entweder bestimmen, welche Quelldatei diese Funktion bereitstellt, oder Bash einfach anweisen, Ihre Anmeldeumgebung einzubeziehen.

#!/bin/bash -l
echo $(realpath "$1")
slm
quelle
Es ist eine Funktion, siehe Bearbeiten
Francis
@Francis - ja, die Funktionen sind nicht enthalten, wenn Sie Ihr Skript aufrufen. Sie müssen sie beschaffen, wenn Sie möchten, dass sie mitkommen. Finden Sie heraus, welche Datei die Funktion bereitstellt, und geben Sie sie als Quelle an. Wenn Sie nur Ihre ganze Umgebung wollen. dann Ihren Anruf bash ändern, #!/bin/bash -l.
slm
Wie finde ich heraus, woher diese Funktion kommt?
Francis
1
@mikeserv - danke, als ich das geschrieben habe, habe ich noch Fedora 14 verwendet, das nicht enthalten war realpath. Mein Fedora 19-System enthält jetzt dieses Tool. Beachten Sie auch, dass das OP einen Debian-Kernel mit 2.6 verwendete, so dass auch sein System realpathaufgrund seines Alters fehlte .
slm
1
@mikeserv - ja, ich war überrascht, das ist jetzt ein altmodischer Q, aber die Informationen über commandwaren mir immer noch nützlich. Es ist eine portablere Möglichkeit, das zu tun, was ich in POSIX-Shells gezeigt habe.
slm
27

Es gibt mindestens zwei Programme, die aufgerufen werden realpath:

  • Ein altes Programm von damals, als GNU coreutils nicht enthalten war readlink -f. Es wird jetzt zu Gunsten von veraltet readlink -f, so viele Distributionen haben aufgehört, es zu führen.
  • Das realpathin GNU coreutils 8.15 eingeführte Programm. Dies ist zu alt, um in Debian zu quetschen oder gar zu keuchen; Zum Zeitpunkt des Schreibens wird Debian Unstable auch nicht ausgeliefert . Dieses Programm ist sehr nah an readlink -f.

Aus irgendeinem Grund haben Sie eine Shell-Funktion, die teilweise das Verhalten von emuliert realpath. Diese Emulation ist teilweise: Wenn Sie sie auf einer symbolischen Verknüpfung aufrufen, folgt sie nicht der symbolischen Verknüpfung.

Da es sich um eine Shell-Funktion handelt, die vermutlich von oder über geladen wird .bashrc, ist sie nur für Code verfügbar, der in Ihrer interaktiven Shell ausgeführt wird. Wenn Sie möchten, dass es anderen Programmen zur Verfügung steht, sofern Sie Linux verwenden, erstellen Sie ein Skript, das Folgendes emuliert realpath:

#!/bin/sh
readlink -f -- "$@"

(Dies emuliert nicht die realpathselten verwendeten Befehlszeilenoptionen.)

Gilles 'SO - hör auf böse zu sein'
quelle
2
Ich kann im Git Repo realpathvon Coreutils keine Beweise dafür finden, dass das Programm von Coreutils als veraltet oder nicht standardmäßig erstellt gilt. Debian muss es also entfernen.
Kaz
@Kaz Oh, gut, nur um die Sache zu komplizieren, hat Coreutils kürzlich (8.15) eine realpathBinärdatei eingeführt, die nahe beieinander liegt, aber nicht genau mit dieser identisch ist readlink -f. Debian Stable enthält 8.13. Debian Unstable entschied sich, das Legacy-Programm beizubehalten .
Gilles 'SO- hör auf böse zu sein'
Es war nicht , dass vor kurzem - es war Jan 2012 savannah.gnu.org/forum/forum.php?forum_id=7076
mikeserv
1
@mikeserv Viel zu aktuell für die Distribution in der Frage (Debian Squeeze). Auch für den aktuellen Debian-Stall noch zu aktuell.
Gilles 'SO- hör auf böse zu sein'
Das ist irgendwie beängstigend. Wie alt ist sie openssl?
mikeserv
8

Es funktioniert nur in der Shell, da die Skriptdatei einen anderen Gültigkeitsbereich hat und keinen Zugriff auf Ihre lokalen Funktionen und Aliase hat, die in Ihren RC- Dateien definiert sind. Und ein realpathBefehl ist in Ihrem System tatsächlich nicht vorhanden.

Also entweder realpathaus dem Paket installieren , eine eigene Funktion definieren (als Teil des Skripts, einige Beispiele prüfen ) oder die RC- Datei in Ihrem Skript ausgeben , in der sie definiert ist (z . ~/.bashrc. B. ).


Hier sind die Schritte zum Installieren, realpathwenn es nicht vorhanden ist:

  • Ubuntu: sudo apt-get install coreutils
  • OS X: brew install coreutils

Ubuntu & Debian

Unter Debian oder Ubuntu realpathsollte das standardmäßig installiert sein. Ich habe das aktuelle Debian 8 (Jessie) eingecheckt und es scheint coreutilsstandardmäßig installiert zu sein.

Getestet mit frischen VM-Images:

$ vagrant init debian/jessie64 && vagrant up --provider virtualbox && vagrant ssh
$ vagrant init ubuntu/vivid64 && vagrant up --provider virtualbox && vagrant ssh

Dann in VM:

$ type -a realpath
realpath is /usr/bin/realpath

Stattdessen realpathkönnen Sie auch das Paket readlink -f file(oder greadlink) verwenden coreutils.

Kenorb
quelle
5
$ sudo apt-get install realpath
user175315
quelle