Wenn ich Skripte in Bash ausführe, muss ich ./
am Anfang schreiben :
$ ./manage.py syncdb
Wenn nicht, erhalte ich eine Fehlermeldung:
$ manage.py syncdb
-bash: manage.py: command not found
Was ist der Grund dafür? Ich dachte, es .
ist ein Alias für den aktuellen Ordner, und daher sollten diese beiden Aufrufe gleichwertig sein.
Ich verstehe auch nicht, warum ich ./
beim Ausführen von Anwendungen nicht benötige , wie zum Beispiel:
user:/home/user$ cd /usr/bin
user:/usr/bin$ git
(was ohne läuft ./
)
bash
shell
unix
command-line
Dan Abramov
quelle
quelle
Antworten:
Denn unter Unix befindet sich das aktuelle Verzeichnis normalerweise nicht
$PATH
.Wenn Sie einen Befehl eingeben, sucht die Shell nach einer Liste von Verzeichnissen, die von der
PATH
Variablen angegeben werden . Das aktuelle Verzeichnis befindet sich nicht in dieser Liste.Der Grund dafür, dass das aktuelle Verzeichnis nicht in dieser Liste enthalten ist, ist die Sicherheit.
Angenommen, Sie sind root und gehen in das Verzeichnis eines anderen Benutzers und geben
sl
stattdessen einls
. Wenn sich das aktuelle Verzeichnis befindetPATH
, versucht die Shell, dassl
Programm in diesem Verzeichnis auszuführen (da es kein anderessl
Programm gibt). Diesessl
Programm könnte bösartig sein.Dies funktioniert,
./
da POSIX angibt, dass ein Befehlsname, der a enthält,/
direkt als Dateiname verwendet wird, wodurch eine Suche in unterdrückt wird$PATH
. Sie hätten den vollständigen Pfad für genau den gleichen Effekt verwenden können,./
ist jedoch kürzer und einfacher zu schreiben.BEARBEITEN
Dieser
sl
Teil war nur ein Beispiel. Die Verzeichnisse inPATH
werden nacheinander durchsucht, und wenn eine Übereinstimmung hergestellt wird, wird dieses Programm ausgeführt. Je nachdem, wie esPATH
aussieht, reicht es möglicherweise aus, einen normalen Befehl einzugeben, um das Programm im aktuellen Verzeichnis auszuführen.quelle
ls
ausführbare Datei enthält ..\my.bat
sl
Befehl namens Dampflokomotive gibt, obwohl standardmäßig nicht verfügbarWenn bash die Befehlszeile interpretiert, sucht es an den in der Umgebungsvariablen beschriebenen Stellen nach Befehlen
$PATH
. Um es zu sehen, geben Sie Folgendes ein:Sie haben einige Pfade, die durch Doppelpunkte getrennt sind. Wie Sie sehen werden, ist der aktuelle Pfad
.
normalerweise nicht in$PATH
. Daher kann Bash Ihren Befehl nicht finden, wenn er sich im aktuellen Verzeichnis befindet. Sie können es ändern, indem Sie:Diese Zeile fügt das aktuelle Verzeichnis hinzu,
$PATH
damit Sie Folgendes tun können:Es wird nicht empfohlen, da es Sicherheitsprobleme gibt und Sie seltsame Verhaltensweisen haben können,
.
die von dem Verzeichnis abhängen, in dem Sie sich befinden :)Vermeiden:
Da können Sie einen Standardbefehl „maskieren“ und die Tür für Sicherheitsverletzungen öffnen :)
Nur meine zwei Cent.
quelle
Ihr Skript in Ihrem Ausgangsverzeichnis wird nicht gefunden, wenn die Shell die
$PATH
Umgebungsvariable überprüft, um Ihr Skript zu finden.Das
./
lautet "Suchen Sie im aktuellen Verzeichnis nach meinem Skript, anstatt alle in angegebenen Verzeichnisse zu suchen$PATH
".quelle
Wenn Sie das '.' Sie geben im Wesentlichen den "vollständigen Pfad" zum ausführbaren Bash-Skript an, sodass Ihre Shell Ihre PATH-Variable nicht überprüfen muss. Ohne das '.' Ihre Shell sucht in Ihrer PATH-Variablen (die Sie durch Ausführen
echo $PATH
sehen können, um festzustellen , ob der von Ihnen eingegebene Befehl in einem der Ordner in Ihrem PATH gespeichert ist. Wenn dies nicht der Fall ist (wie dies bei manage.py der Fall ist), wird dies angegeben Die Datei kann nicht gefunden werden. Es wird als schlechte Praxis angesehen, das aktuelle Verzeichnis in Ihren PATH aufzunehmen, was hier ziemlich gut erklärt wird: http://www.faqs.org/faqs/unix-faq/faq/part2/section- 13.htmlquelle
Unter * nix befindet sich das aktuelle Verzeichnis im Gegensatz zu Windows normalerweise nicht in Ihrer
$PATH
Variablen. Daher wird das aktuelle Verzeichnis bei der Ausführung von Befehlen nicht durchsucht. Sie brauchen nicht./
zum Ausführen von Anwendungen , da diese Anwendungen sind in Ihrem $ PATH; höchstwahrscheinlich sind sie in/bin
oder/usr/bin
.quelle
Diese Frage hat bereits einige großartige Antworten, aber ich wollte das hinzufügen, wenn sich Ihre ausführbare Datei auf dem Pfad befindet und Sie beim Ausführen sehr unterschiedliche Ausgaben erhalten
zu denen, die du bekommst, wenn du rennst
(Nehmen wir an, Sie stoßen mit der einen und nicht mit der anderen auf Fehlermeldungen), dann könnte das Problem darin bestehen, dass Sie zwei verschiedene Versionen der ausführbaren Datei auf Ihrem Computer haben: eine auf dem Pfad und die andere nicht.
Überprüfen Sie dies durch Ausführen
welche ausführbare Datei
und
Es hat meine Probleme behoben ... Ich hatte drei Versionen der ausführbaren Datei, von denen nur eine für die Umgebung korrekt kompiliert wurde.
quelle
Begründung für die
/
POSIX PATH-RegelDie Regel wurde erwähnt unter: Warum benötigen Sie ./ (Schrägstrich) vor der ausführbaren Datei oder dem Skriptnamen, um sie in Bash auszuführen? aber ich möchte näher erläutern, warum ich denke, dass dies ein gutes Design ist.
Erstens lautet eine explizite Vollversion der Regel:
/
( zum Beispiel./someprog
,/bin/someprog
,./bin/someprog
): CWD verwendet wird und ist nicht PATH/
(z. B.someprog
): PATH wird verwendet und CWD nichtAngenommen, es läuft:
würde suchen:
Dann, wenn Sie
/bin/someprog
von Ihrer Distribution weglaufen wollten und Sie taten:es würde manchmal funktionieren, aber andere würden fehlschlagen, weil Sie sich möglicherweise in einem Verzeichnis befinden, das ein anderes nicht verwandtes
someprog
Programm enthält .Daher würden Sie bald feststellen, dass dies nicht zuverlässig ist, und Sie würden am Ende immer absolute Pfade verwenden, wenn Sie PATH verwenden möchten, wodurch der Zweck von PATH zunichte gemacht wird.
Dies ist auch der Grund, warum es eine wirklich schlechte Idee ist, relative Pfade in Ihrem Pfad zu haben. Ich sehe dich an
node_modules/bin
.Nehmen wir umgekehrt an, dass Laufen:
Würde suchen:
Wenn Sie dann gerade ein Skript
someprog
aus einem Git-Repository heruntergeladen und von CWD ausführen möchten, wären Sie sich nie sicher, ob dies das eigentliche Programm ist, das ausgeführt wird, da Ihre Distribution möglicherweise Folgendes hat:Das ist in dir PATH von einem Paket, das du installiert hast, nachdem du letztes Jahr nach Weihnachten zu viel getrunken hast.
Daher wären Sie erneut gezwungen, immer lokale Skripte relativ zu CWD mit vollständigen Pfaden auszuführen, um zu wissen, was Sie ausführen:
das wäre auch extrem nervig.
Eine andere Regel, die Sie möglicherweise in Versuchung führen könnten, wäre:
Dies zwingt die Benutzer jedoch erneut dazu, für Nicht-PATH-Skripte mit immer absolute Pfade zu verwenden
"$(pwd)/someprog"
.Die
/
Pfadsuchregel bietet eine einfach zu merkende Lösung für das About-Problem:PATH
PATH
Dies macht es sehr einfach, immer zu wissen, was Sie ausführen, indem Sie sich auf die Tatsache verlassen, dass Dateien im aktuellen Verzeichnis entweder als
./somefile
oder ausgedrückt werden könnensomefile
, und gibt daher einer von ihnen eine besondere Bedeutung.Manchmal ist es etwas ärgerlich, dass Sie nicht
some/prog
relativ zu suchen könnenPATH
, aber ich sehe keine vernünftigere Lösung dafür.quelle
Wenn sich das Skript nicht im Pfad befindet, ist dies erforderlich. Weitere Informationen finden Sie unter http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html
quelle
Alle haben eine gute Antwort auf die Frage, und ja, dies gilt nur, wenn sie im aktuellen Verzeichnis ausgeführt werden, es sei denn, Sie geben den absoluten Pfad an. Siehe meine Beispiele unten.
Außerdem machte der (Punkt-Schrägstrich) für mich Sinn, wenn ich den Befehl für den untergeordneten Ordner tmp2 (/ tmp / tmp2) habe und ihn verwendet (doppelter Punkt-Schrägstrich).
STICHPROBE:
quelle