Kiedy uruchamiam skrypty w bash, muszę napisać ./
na początku:
$ ./manage.py syncdb
Jeśli nie, otrzymuję komunikat o błędzie:
$ manage.py syncdb
-bash: manage.py: command not found
Jaki jest tego powód? Myślałem, że .
to alias dla bieżącego folderu, dlatego te dwa połączenia powinny być równoważne.
Nie rozumiem też, dlaczego nie potrzebuję, ./
gdy uruchamiam aplikacje, takie jak:
user:/home/user$ cd /usr/bin
user:/usr/bin$ git
(który działa bez ./
)
bash
shell
unix
command-line
Dan Abramov
źródło
źródło
Odpowiedzi:
Ponieważ w systemie Unix zwykle nie ma bieżącego katalogu
$PATH
.Po wpisaniu polecenia powłoka wyszukuje listę katalogów określoną przez
PATH
zmienną. Bieżącego katalogu nie ma na tej liście.Przyczyną braku bieżącego katalogu na tej liście są zabezpieczenia.
Powiedzmy, że jesteś rootem, idź do katalogu innego użytkownika i wpisz
sl
zamiastls
. Jeśli bieżący katalog się znajdujePATH
, powłoka spróbuje uruchomićsl
program w tym katalogu (ponieważ nie ma innegosl
programu). Żesl
program może być złośliwy.Działa z,
./
ponieważ POSIX określa, że nazwa polecenia, która zawiera,/
zostanie użyta bezpośrednio jako nazwa pliku, uniemożliwiając wyszukiwanie$PATH
. Możesz użyć pełnej ścieżki dla tego samego efektu, ale./
jest krótszy i łatwiejszy do napisania.EDYTOWAĆ
Ta
sl
część była tylko przykładem. Katalogi wPATH
są przeszukiwane sekwencyjnie, a po dopasowaniu program jest wykonywany. Tak więc, w zależności odPATH
wyglądu, wpisanie normalnego polecenia może, ale nie musi wystarczyć do uruchomienia programu w bieżącym katalogu.źródło
ls
plik wykonywalny..\my.bat
itp.sl
polecenie o nazwie lokomotywa parowa, chociaż domyślnie niedostępne ;-)Kiedy bash interpretuje wiersz poleceń, szuka poleceń w lokalizacjach opisanych w zmiennej środowiskowej
$PATH
. Aby to zobaczyć, wpisz:Będziesz miał kilka ścieżek oddzielonych dwukropkami. Jak zobaczysz, bieżącej ścieżki
.
zwykle nie ma$PATH
. Więc Bash nie może znaleźć twojego polecenia, jeśli znajduje się w bieżącym katalogu. Możesz to zmienić, mając:Ta linia dodaje bieżący katalog,
$PATH
dzięki czemu możesz:Nie jest to zalecane, ponieważ ma problem z bezpieczeństwem, a ponadto możesz mieć dziwne zachowania, jak
.
zależy to od katalogu, w którym się znajdujesz :)Uniknąć:
Jak możesz „zamaskować” jakieś standardowe polecenie i otworzyć drzwi do naruszenia bezpieczeństwa :)
Tylko moje dwa centy.
źródło
Skrypt znajdujący się w katalogu domowym nie zostanie znaleziony, gdy powłoka spojrzy na
$PATH
zmienną środowiskową w celu znalezienia skryptu../
Mówi „wygląd w bieżącym katalogu dla mojego skryptu zamiast patrząc na wszystkich katalogach określonych w$PATH
”.źródło
Gdy dodasz „.” zasadniczo podajesz „pełną ścieżkę” do wykonywalnego skryptu bash, więc twoja powłoka nie musi sprawdzać zmiennej PATH. Bez '.' twoja powłoka zajrzy do zmiennej PATH (którą możesz zobaczyć, uruchamiając,
echo $PATH
aby sprawdzić, czy wpisane polecenie mieszka w którymkolwiek z folderów PATH. Jeśli tak nie jest (jak w przypadku manage.py), to mówi nie można znaleźć pliku. Złą praktyką jest dołączanie bieżącego katalogu do PATH, co jest dość dobrze wyjaśnione tutaj: http://www.faqs.org/faqs/unix-faq/faq/part2/section- 13.htmlźródło
W systemie * nix, w przeciwieństwie do systemu Windows, bieżącego katalogu zwykle nie ma w
$PATH
zmiennej. Dlatego bieżący katalog nie jest przeszukiwany podczas wykonywania poleceń. Nie musisz./
uruchamiać aplikacji, ponieważ te aplikacje znajdują się w $ PATH; najprawdopodobniej są w/bin
lub/usr/bin
.źródło
To pytanie ma już niesamowite odpowiedzi, ale chciałem dodać, że jeśli twój plik wykonywalny znajduje się na PATH, a po uruchomieniu masz bardzo różne dane wyjściowe
do tych, które dostaniesz, jeśli uciekniesz
(powiedzmy, że napotykasz komunikaty o błędach z jednym, a nie drugim), problem może polegać na tym, że masz dwie różne wersje pliku wykonywalnego na swoim komputerze: jeden na ścieżce, a drugi nie.
Sprawdź to, uruchamiając
który jest wykonywalny
i
Naprawiło to moje problemy ... Miałem trzy wersje pliku wykonywalnego, z których tylko jedna została poprawnie skompilowana dla środowiska.
źródło
Uzasadnienie dla
/
reguły POSIX PATHReguła została wspomniana na stronie: Dlaczego potrzebujesz ./ (kropka-ukośnik) przed nazwą pliku wykonywalnego lub skryptu, aby uruchomić ją w trybie bash? ale chciałbym bardziej szczegółowo wyjaśnić, dlaczego uważam, że to dobry projekt.
Po pierwsze, wyraźna pełna wersja reguły to:
/
(na przykład./someprog
,/bin/someprog
,./bin/someprog
) CWD jest używany i ścieżka nie jest/
(np.someprog
): używana jest ŚCIEŻKA, a CWD nieZałóżmy teraz, że działa:
szukałby:
Następnie, jeśli chcesz uciec
/bin/someprog
z dystrybucji, a zrobiłeś:czasami to działałoby, ale innym się nie udawało, ponieważ możesz znajdować się w katalogu, który zawiera inny niepowiązany
someprog
program.Dlatego wkrótce dowiesz się, że nie jest to wiarygodne, i zawsze będziesz używał ścieżek bezwzględnych, gdy chcesz użyć ŚCIEŻKI, co pokona cel ŚCIEŻKI.
Dlatego też posiadanie ścieżek względnych w ŚCIEŻCE jest naprawdę złym pomysłem. Ja patrząc na ciebie,
node_modules/bin
.I odwrotnie, załóżmy, że działa:
Wyszukiwałby:
Następnie, jeśli właśnie pobrałeś skrypt
someprog
z repozytorium git i chciałbyś go uruchomić z CWD, nigdy nie byłbyś pewien, że to byłby właściwy program, ponieważ może twoja dystrybucja ma:który jest w TWOJEJ ŚCIEŻCE z jakiegoś pakietu, który zainstalowałeś po wypiciu za dużo po Bożym Narodzeniu w zeszłym roku.
Dlatego po raz kolejny będziesz zmuszony zawsze uruchamiać lokalne skrypty względem CWD z pełnymi ścieżkami, aby wiedzieć, co uruchamiasz:
co byłoby również bardzo denerwujące.
Kolejną zasadą, którą możesz pokusić się o wymyślenie, byłoby:
ale po raz kolejny zmusza to użytkowników do korzystania ze ścieżek bezwzględnych dla skryptów innych niż PATH
"$(pwd)/someprog"
./
Reguła przeszukiwanie ścieżki oferuje prosty do zapamiętania rozwiązanie dotyczące problemu:PATH
PATH
co sprawia, że bardzo łatwo jest zawsze wiedzieć, co się uruchamia, polegając na tym, że pliki w bieżącym katalogu można wyrazić jako
./somefile
lubsomefile
, i dlatego nadaje to jednemu z nich specjalne znaczenie.Czasami jest trochę denerwujące, że nie można szukać
some/prog
krewnegoPATH
, ale nie widzę rozsądniejszego rozwiązania tego problemu.źródło
Jeśli skrypt nie znajduje się na ścieżce, jest to wymagane. Aby uzyskać więcej informacji, przeczytaj http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html
źródło
Wszystko ma świetną odpowiedź na pytanie, i tak, dotyczy to tylko uruchomienia go w bieżącym katalogu, chyba że podasz ścieżkę bezwzględną. Zobacz moje próbki poniżej.
Również (kropka-ukośnik) miało dla mnie sens, gdy mam polecenie w folderze podrzędnym tmp2 (/ tmp / tmp2) i używa (podwójnego ukośnika).
PRÓBA:
źródło