Dlaczego używamy ./filename
do wykonania pliku w systemie Linux?
Dlaczego nie po prostu wprowadź go tak jak inne polecenia gcc
, ls
itd …
Komentarze
Answer
W systemie Linux, UNIX i pokrewnych systemach operacyjnych .
oznacza bieżący katalog. Ponieważ chcesz uruchomić plik w bieżącym katalogu i w tym katalogu nie ma w Twoim $PATH
, potrzebujesz bitu ./
, aby wskazać powłoce, gdzie plik wykonywalny to. Tak więc ./foo
oznacza uruchomienie pliku wykonywalnego o nazwie foo
, który znajduje się w tym katalogu.
Możesz użyć type
lub which
, aby uzyskać pełną ścieżkę do wszelkich poleceń znajdujących się w $PATH
.
Komentarze
- Wykonywanie programów w bieżącym katalogu jest bardzo powszechne. Dlaczego nie ' nie szuka tam również powłoki? Najpierw wyszukuje w., A następnie w $ PATH.
- istnieją również
alias
elementy, które mogą przeszkadzać, a nie tylko$PATH
. - @Michael bezpieczeństwo i zdrowie psychiczne: jeśli najpierw wyszukałby w
.
, byłby to problem z bezpieczeństwem, Ty lub ktoś inny mógłby zastąpić Na przykładls
(prosty wirus / trojen: utwórz plik zip z plikiem wykonywalnym o nazwiels
, gdy ktoś przeszukuje, uruchamiają ten plik wykonywalny…). Jeśli przeszukiwał.
jako ostatni, możesz spędzić dużo czasu na szaleństwie nie wiedząc dlaczego twój program nie działa (np. Tworzysz program o nazwie test, zamiast go uruchamiać program do testowania systemów. Który nie daje żadnych wyników). - @jcubic to ' to zły pomysł. Zobacz komentarz powyżej. W przeszłości przeszukiwania DOS w bieżącym katalogu i to zachowanie zostało przeniesione do cmd systemu Windows, co wprowadza wiele problemów związanych z bezpieczeństwem. MS naprawiło to w PowerShell i teraz musisz użyć. \ Aby uruchomić program w bieżącym katalogu
- @ ctrl-alt-delor: Kiedy byłem na uniwersytecie pod koniec lat 80-tych ' s, była to powszechna (zabroniona) taktyka. Pisanie programu ” ls ” i pozostawienie go w folderze domowym na wypadek, gdyby ktoś przyszedł węszyć. Program został nazwany ” get shell ” IIRC. Próbowałaby uzyskać dane uwierzytelniające użytkownika uruchamiającego polecenie – a następnie może wydrukować fałszywą listę katalogów, aby pozostawić go nieświadomym.
Odpowiedź
Dosłowna odpowiedź jest taka, jak podali inni: ponieważ bieżący katalog nie znajduje się w twoim $PATH
.
Ale dlaczego? Krótko mówiąc, chodzi o bezpieczeństwo. Jeśli szukasz katalogu domowego innej osoby (lub / tmp) i wpisz po prostu gcc
lub ls
, chcesz wiesz, że „używasz prawdziwej, a nie złośliwej wersji, którą napisał twój przyjaciel dowcipniś i która usuwa wszystkie twoje pliki. Innym przykładem może być test
lub [
, który może przesłonić te polecenia w skryptach powłoki, jeśli twoja powłoka nie ma ich jako wbudowanych.
Mając .
jako ostatni wpis na twojej ścieżce jest nieco bezpieczniejszy, ale są też inne ataki, które to wykorzystują. Prostym sposobem jest wykorzystanie typowych literówek, takich jak sl
lub ls-l
. Lub znajdź typowe polecenie, które nie jest zainstalowane w tym systemie – na przykład vim
, ponieważ administratorzy systemu mają ponadprzeciętne prawdopodobieństwo, że je wpiszą.
Czy to brzmi zbyt teoretycznie? w dużej mierze tak jest, ale z pewnością może się to zdarzyć w rzeczywistości, zwłaszcza w systemach z wieloma użytkownikami. W rzeczywistości tutaj jest przykład z tej witryny , w której administrator przełączył się do katalogu domowego użytkownika i znalazł ps
być maskowane przez plik wykonywalny o tej nazwie.
Komentarze
- Po prostu podaj bezwzględne ścieżki w
PATH
zmienna środowiskowa.
Odpowiedź
Jeśli masz na myśli, dlaczego potrzebujesz./ na początku – to dlatego, że (w przeciwieństwie do Windows), bieżący katalog nie jest domyślnie częścią ścieżki. Jeśli uruchomisz:
$ ls
Twoja powłoka szuka ls
w katalogach w zmiennej środowiskowej PATH (echo $PATH
, aby go zobaczyć) i uruchamia pierwszy znaleziony plik wykonywalny o nazwie ls
. Jeśli wpiszesz:
$ a.out
powłoka zrobi to samo – ale prawdopodobnie nie znajdzie pliku wykonywalnego o nazwie a.out. Musisz powiedzieć powłoce gdzie a.out jest – czy znajduje się w bieżącym katalogu (.), to ścieżka to ./a.out
.
Jeśli „pytasz, dlaczego to się nazywa „a.out”, to tylko domyślna nazwa pliku wyjściowego dla gcc. Możesz ją zmienić za pomocą argumentu wiersza poleceń -o. Na przykład:
$ gcc test.c -o test $ ./test
Komentarze
- Dzięki. Wątpię, dlaczego potrzebujesz ./ na początku …. Użyłem „.” (aby przejść do bieżącego katalogu), ale dlaczego ” / ” po tym?
- / jest separatorem ścieżek w Linuksie, więc używasz go do oddzielenia katalogu (.) od nazwy pliku (a.out). Bez niego masz .a.out, który jest prawidłowym nazwa pliku sama w sobie. (Spróbuj
touch .a.out; ls -lA
, aby to zobaczyć). - tak określasz ścieżka w systemie Unix,
<dir>/<file>
, więc w zasadzie mówisz o wykonaniu pliku w bieżącym katalogu, na co wskazuje./test
- Red Hat Linux 9? Czas na aktualizację!
- W systemie Windows 10 PowerShell jest teraz domyślną powłoką i wymaga również
./
, aby uruchomić plik wykonywalny w bieżącej ścieżce
Odpowiedź
Możesz spróbować dodać :.
do zmiennej $ PATH.
Spróbuj ALT + F2 i wpisz: gksudo gedit /etc/environment
jeśli używasz Linuksa / GTK (to masz, jeśli używasz Ubuntu).
JEDNAK, Zdecydowanie odradzam tego robić. Jest źle, źle, źle i źle.
Wiesz, takie rzeczy działają od 1970 roku. Jest powód, dla którego bieżący katalog nie jest uwzględniony w $ PATH.
.
to bieżący katalog
.something
byłby plikiem ukrytym (wpisz „ALT +”, aby pojawiają się w Nautilusie lub spróbuj „ls -la
„.
./someProgram.sh
jest tym, co wpisujesz, aby URUCHOMIĆ plik wykonywalny jakiśProgram .sh w bieżącym katalogu.
.somethingElse
oznaczałoby, że masz ukryty plik wykonywalny w bieżącym katalogu, co jest złym pomysłem.
Odpowiedź
Bardziej kompletna reguła to w rzeczywistości: jeśli jakikolwiek ukośnik /
znajduje się na ścieżce, nie szukaj” t PATH
Zanim przejdziemy do uzasadnienie, powinieneś najpierw wiedzieć o tym fakcie: uruchamianie jednego z:
bin/someprog
lub:
lub:
cd bin ./myexec
wykonaj bin/someprog
bez wyszukiwania PATH
z dokładnie tego samego powodu: wszystkie bin/someprog
, /bin/someprog
i ./someprog
mają w sobie ukośnik /
.
someprog
sam nie ma ukośnika /
, dlatego wyszukuje tylko w PATH
.
POSIX 7 określa tę regułę pod adresem: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
PATH
[…] Jeśli poszukiwana nazwa ścieżki zawiera
<slash>
, przeszukiwanie prefiksów ścieżki nie będzie przeprowadzane .
Uzasadnienie dla /
POSIX PATH
Załóżmy, że działa:
someprog
wyszukałoby:
- najpierw względem CWD
- względne do PATH po
Następnie, jeśli chcesz uruchomić /bin/someprog
ze swojej dystrybucji, a zrobiłeś:
someprog
czasami działało, ale w innych nie, ponieważ możesz być w katalogu, który zawiera inny niepowiązany program someprog
.
Dlatego wkrótce dowiesz się, że nie jest to wiarygodne i zawsze będziesz używać ścieżki bezwzględne, gdy chcesz używać PATH, co jest sprzeczne z celem PATH.
Dlatego też posiadanie ścieżek względnych w PATH jest naprawdę złym pomysłem. Patrzę na Ciebie , node_modules/bin
.
I odwrotnie, załóżmy, że uruchomienie:
./someprog
spowoduje wyszukanie:
- najpierw względem PATH
- względne w stosunku do CWD po
Następnie, jeśli właśnie pobrałeś skrypt someprog
z repozytorium git i chciałeś go uruchomić z CWD, nigdy nie byłbyś pewien, że to jest rzeczywisty program, który by działał, ponieważ być może twoja dystrybucja ma:
/bin/someprog
, który jest w Tobie ŚCIEŻKA z jakiś pakiet, który zainstalowałeś po wypiciu zbyt dużej ilości alkoholu po Bożym Narodzeniu w zeszłym roku.
Dlatego po raz kolejny będziesz zmuszony zawsze uruchamiać lokalne skrypty w stosunku do CWD z pełnymi ścieżkami, aby wiedzieć, co uruchamiasz:
"$(pwd)/someprog"
, co również byłoby bardzo irytujące.
Inna zasada, która mogłaby Cię wymyślić, to:
ścieżki względne używają tylko PATH, ścieżki bezwzględne tylko CWD
ale po raz kolejny zmusza to użytkowników do zawsze używaj abso lute ścieżki dla skryptów innych niż PATH z "$(pwd)/someprog"
.
/
reguła wyszukiwania ścieżki oferuje łatwe do zapamiętania rozwiązanie do problemu:
- ukośnik: nie używaj
PATH
- bez ukośnika: używaj tylko
PATH
co sprawia, że zawsze łatwo zorientujesz się, co uruchamiasz, polegając na fakcie, że pliki w bieżącym katalogu można wyrazić jako ./somefile
lub somefile
, więc nadaje to szczególne znaczenie jednemu z nich.
Czasami jest nieco irytujące, że nie można wyszukiwać dla some/prog
w stosunku do PATH
, ale nie widzę rozsądniejszego rozwiązania tego problemu.
./command_name
do wykonania polecenia w systemie Linux? ”