Ist ./ (Punktschrägstrich) ein Befehl?

15

Kern der Frage:

Die Frage stellte sich, als ich die Software nicht installieren konnte, und ich frage wirklich nach ./, weil ich nichts davon wusste und die Ausgabe "Befehl nicht gefunden" mich verwirrte, was der Befehl eigentlich war.

Kontext:

Ich möchte die Datei installieren truecrypt-7.2-setup-x86.

Anweisungen sagen, um den Befehl zu verwenden:

sudo ./truecrypt-7.2-setup-x86

Aber die Ausgabe ist:

sudo: ./truecrypt-7.2-setup-x86: command not found

UPDATE: Der Vollständigkeit halber befand ich mich im Test im Dateiordner, hatte aber die Datei noch nicht ausführbar gemacht (chmod + x).

Ubuntubu
quelle
1
Der ./Teil des Befehls lautet: "Sehen Sie sich das aktuelle Verzeichnis an und führen Sie von hier aus den Befehl 'truecrypt-7.2-setup-x86' aus." Sie müssen diesen Befehl in dem Verzeichnis ausführen, in das Sie die Datei entpackt haben.
Charles Green
2
@Videonauth - Nicht wirklich, ich persönlich glaube nicht, dass es auf die Ebene einer Antwort steigt.
Charles Green
1
@Zanna Ich habe ein Skript ohne Ausführungsberechtigungen getestet und der Fehler war ein fehlender Berechtigungsfehler, kein nicht gefundener Befehl.
Charles Green
2
@ubuntubu OK, sehr gut, Sie sind in das Verzeichnis umgezogen - gut. Kleiner Kommentar zur Bearbeitung. Der Befehl sollte sein chmod +x, das chmod -xist das Gegenteil - es entfernt ausführbare Berechtigungen
Sergiy Kolodyazhnyy
4
Der Fragentitel unterscheidet sich stark vom Text. Vielleicht sollte das behoben werden?
David Z

Antworten:

24

./ist kein Befehl. Der Befehl lautet ./truecrypt-7.2-setup-x86.

Ihre Shell und Programme wie sudobehandeln einen Befehl als Pfadnamen, wenn er mindestens ein /Zeichen enthält. Da es sich .um das Verzeichnis handelt, in dem Sie sich gerade befinden, wird ./truecrypt-7.2-setup-x86die Datei truecrypt-7.2-setup-x86im aktuellen Verzeichnis benannt. Wenn keine solche Datei vorhanden ist oder die Datei nicht ausgeführt werden kann, wird eine Fehlermeldung angezeigt.

Wenn ein Befehl keinen Schrägstrich enthält, werden die darin aufgeführten Verzeichnisse danach $PATHdurchsucht, wie Sergiy Kolodyazhnyy sagt . Das aktuelle Verzeichnis ist gesucht nicht automatisch - und es wird nicht zu setzen empfohlen .in $PATH. Auf diese Weise führen Sie nicht versehentlich Dinge aus, von denen Sie nicht erwartet hatten, dass sie ausgeführt werden, weil Sie zufällig cdd in einem Verzeichnis haben, das sie enthält.

Schreiben Sie ./vor dem Namen einer ausführbaren Datei im aktuellen Verzeichnis die übliche Methode , um sie auszuführen, dies ist jedoch keine spezielle Syntax. Wenn Sie zum Beispiel Ihren Code durcheinander gebracht haben $PATHund einen Befehl wie diesen ausführen müssen ls, können Sie schreiben /bin/ls. Nein .ist in diesem Fall oder im Allgemeinen notwendig; Was benötigt wird, ist ein /Punkt im Pfadnamen, der anzeigt, dass es sich um einen Pfadnamen handelt.

Da .es sich immer um das aktuelle Verzeichnis und /nur um das Verzeichnistrennzeichen handelt, müssen Sie zunächst überprüfen, ob die von Ihnen angegebene Datei tatsächlich im aktuellen Verzeichnis vorhanden ist. (Wenn dies der Fall ist, überprüfen Sie die Berechtigungen , wie Charles Green erläutert . Wenn Sie die Datei jedoch aus einem Archiv extrahiert haben, verfügt sie normalerweise bereits über ausführbare Berechtigungen, wenn sie ausgeführt werden soll.)

Eliah Kagan
quelle
21

Der Teil ./ des Befehls lautet: "Sehen Sie sich das aktuelle Verzeichnis an und führen Sie von hier aus den Befehl 'truecrypt-7.2-setup-x86' aus." Sie müssen diesen Befehl in dem Verzeichnis ausführen, in das Sie die Datei entpackt haben.

Dies kann getestet werden: Geben Sie in demselben Terminalfenster, in dem Sie den Befehl ausführen, den Befehl ein. ls -l true*Befindet sich die Datei im aktuellen Arbeitsverzeichnis, wird eine Liste mit der Datei (und einer Reihe zusätzlicher Informationen) angezeigt.

Wie Zanna in den Kommentaren angemerkt hat, verfügt Ihre Datei möglicherweise nicht über Ausführungsberechtigungen - dies kann leicht behoben werden. Als Testfall zeigt mein Telefonbuch

chick@dad:~/test$ ls -l
total 4
-rw-r--r-- 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

und die Datei "rFullBack" listet "-rw-" als meine Erlaubnis auf, die Datei zu lesen und zu schreiben. Ich kann den Befehl ausführen chmod +x rFullBackund die Verzeichnisliste wechselt zu

chick@dad:~/test$ ls -l
total 4
-rwxr-xr-x 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

Dort sind meine Berechtigungen jetzt '-rwx', was anzeigt, dass ich die Datei ausführen kann.


Kurz gesagt, wenn die Datei in Ihrem Verzeichnis vorhanden ist

Führen Sie den Befehl aus

chmod +x ./truecrypt-7.2-setup-x86

und dann den Befehl

sudo ./truecrypt-7.2-setup-x86
Charles Green
quelle
1
Nicht ganz. Es wird rw-als Ihre Erlaubnis aufgeführt - -davor steht es für Set [gu] id und Sticky Bits.
Duncan X Simpson
@DuncanXSimpson Danke - Ich habe die Beschreibung der Berechtigungen ein wenig aktualisiert, aber ich werde die setguid und die Sticky Bits für diese Antwort ignorieren!
Charles Green
8

Wie funktioniert das Aufrufen von Befehlen in der Shell?

Nein, es ist kein Befehl. Die Art und Weise, wie Shells funktionieren, ist, wenn Sie eine Textzeile eingeben, das erste Wort als Befehl behandelt wird und wenn der Befehl keiner der in der Shell integrierten Befehle ist, werden alle in der PATH Umgebungsvariablen aufgelisteten Speicherorte angezeigt .

Was passiert, wenn sich der Befehl, den Sie ausführen möchten, in demselben Verzeichnis befindet, in dem Sie sich gerade befinden, dieses Verzeichnis jedoch nicht in der Liste der PATHVerzeichnisse aufgeführt ist? Das ist, wenn Sie verwenden müssen ./. Es ist in gewisser Weise genau das Gleiche wie dies der Fall ist /bin/bash- Sie teilen der Shell mit, wo sich Ihr gewünschter Befehl befindet, und geben einen vollständigen Pfad dazu an. Und im Falle von ./ sagst du zu Shell "Schau in dieses Verzeichnis". Ein so wichtiger Teil ist, dass Sie sich in demselben Verzeichnis befinden müssen, in dem sich die Datei befindet.

Natürlich muss das ausführbare Bit gesetzt sein, damit eine ausführbare Datei ausgeführt werden kann chmod +x ./my_file.

Also die wichtigen Schritte:

  1. cd wo Sie die Datei gespeichert haben; wenn es drin ist ~/Downloads, danncd ~/Downloads
  2. Führen Sie chmod +x ./truecrypt-7.2-setup-x86"make file truecrypt-7.2-setup-x86" aus, das sich in diesem Verzeichnis befindet.
  3. Und jetzt tu es sudo ./truecrypt-7.2-setup-x86

Beachten Sie, dass die Verwendung von ./kein zufälliges Verhalten ist, sondern ein Standard, der durch den Portable Operating System Interface-Standard (auch bekannt als POSIX) spezifiziert ist. Weitere Informationen finden Sie im Abschnitt "Befehlssuche und -ausführung".

Reproduzieren des Fehlers

$ # my script is in ~/Downloads folder
$ stat -c "%n" /home/xieerqi/Downloads/my_script.sh                         
/home/xieerqi/Downloads/my_script.sh
$ # if I run sudo ./my_script.sh, we get an error
$ sudo ./my_script.sh
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found
$ # of course the command not found because file is not in ./, not in this dir
$ # this is not  sudo's problem
$ # but sudo does indeed show the same error even if you're in same directory
$ cd ./Downloads/                                                                                                                                                      
$ sudo ./my_script.sh                                                                                                                                                  
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found

HINWEIS : Die Fehlermeldung von sudoist offensichtlich irreführend. Bitte beachten Sie jedoch, dass dies nicht der Kern der Frage war, die OP stellt.

Dokumentation und Referenzen

Ab bashHandbuch 4.3, Abschnitt "BEFEHLSAUSFÜHRUNG":

Wenn der Name weder eine Shell-Funktion noch eine integrierte Funktion ist und keine Schrägstriche enthält, durchsucht bash jedes Element des PATH nach einem Verzeichnis, das eine ausführbare Datei mit diesem Namen enthält.

Von Warum müssen Sie ./ (Punkt-Schrägstrich) vor Skriptnamen es in bash laufen? :

Es funktioniert mit ./, da POSIX angibt, dass ein Befehlsname, der ein / enthält, direkt als Dateiname verwendet wird, wodurch eine Suche in $ PATH unterdrückt wird. Sie hätten den vollständigen Pfad für genau den gleichen Effekt verwenden können, aber ./ ist kürzer und einfacher zu schreiben.

Sergiy Kolodyazhnyy
quelle
Tatsächlich ist die sudoAusgabe irreführend. Wenn Sie das gleiche versuchen , ohne sudo, werden Sie eine andere Fehlermeldung erhalten von bash: Permission denied. Und das zu Recht, da Sie nicht die Berechtigung zum Ausführen des Skripts (über chmod +x) erteilt haben .
Ruslan
@ Ruslan die Tatsache, dass die sudoAusgabe irreführend ist, ist wahr, aber das ist der Fehler, der auftaucht. Möglicherweise müssen Sie dies den Entwicklern melden und sie das Problem beheben lassen. Dies ist jedoch nicht der Kern der Diskussion - wir mussten feststellen, was das OP getan hat, um einen solchen Fehler hervorzurufen, und sie auf den richtigen Weg führen. Ob es irreführend ist oder nicht - darauf kommt es hier nicht an.
Sergiy Kolodyazhnyy
In einer anderen Art und Weise, ist es nicht genau die gleiche wie mit /bin/bash: Es ermöglicht es Ihnen nicht um ein Skript auszuführen , auf das Sie haben keine Berechtigung ausführen. Wenn Sie den Skriptnamen mit einem Vorwort versehen /bin/bash, /bin/bashist nur die ausführbare Datei von Bedeutung, da es sich um den ausgeführten Befehl handelt. Wenn Sie das nicht tun, wird das Skript selbst ausgeführt, was wiederum dazu führt, dass entweder Ihre aktuelle Shell oder das, was sich in der obersten #!Zeile befindet, aufgerufen wird
Monty Harder,
@MontyHarder /bin/bashist hier nur ein Beispiel. Die Tatsache , dass wir fordern /bin/bashund ./script.sh durch Angabe des Pfades zu Sache ausgeführt wird - das ist das gleiche. Voranstellen von Skripten mit bash script.shoder /bin/bash script.shist ein völlig anderes Thema, bei dem Sie eine ausführbare Datei ausführen und Skripten als Argument übergeben - was übrigens zu Problemen führen kann, wenn die Syntax nicht für die von Ihnen aufgerufene Shell geschrieben wird csh. /bin/bashist in Ordnung ausführbar, aber Tatsache ist, dass Sie immer noch den vollständigen Pfad dazu angeben.
Sergiy Kolodyazhnyy
2
@SergiyKolodyazhnyy Das Voranstellen eines Skriptnamens mit /bin/bashoder nur mit bashist auch eine übliche Methode, um den Mangel an ausführbaren Berechtigungen für das Skript zu beheben . Den vollständigen Skript Pfad angeben wird nicht löst dieses Problem. So /bin/bashist ein besonders schlechtes Beispiel in diesem speziellen Fall.
Monty Harder