a.out
Dlaczego podczas uruchamiania programu C , używając terminala Ubuntu, zawsze muszę pisać ./
wcześniej a.out
, a nie tylko pisać a.out
? Czy jest na to rozwiązanie?
a.out
Dlaczego podczas uruchamiania programu C , używając terminala Ubuntu, zawsze muszę pisać ./
wcześniej a.out
, a nie tylko pisać a.out
? Czy jest na to rozwiązanie?
Odpowiedzi:
Po wpisaniu nazwy programu, takiego jak a.out
system, szuka pliku w ŚCIEŻCE. W moim systemie PATH jest ustawione na
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Twój jest prawdopodobnie podobny. Aby to sprawdzić, wpisz echo $PATH
w terminalu.
System przegląda te katalogi w podanej kolejności i jeśli nie może znaleźć, program generuje command not found
błąd.
Wcześniejsze polecenie ./
mówi „zapomnij o ŚCIEŻCE, chcę, żebyś przeglądał tylko bieżący katalog”.
Podobnie możesz nakazać systemowi wyszukiwanie tylko w innym określonym miejscu, poprzedzając polecenie ścieżką względną lub bezwzględną, taką jak:
../
oznacza w katalogu nadrzędnym, np. ../hello
poszukaj hello w katalogu nadrzędnym.
./Debug/hello
: „poszukaj hello
w podkatalogu Debug mojego bieżącego katalogu.”
lub /bin/ls
: „szukaj ls
w katalogu /bin
”
Domyślnie bieżący katalog nie znajduje się na ścieżce, ponieważ jest uważany za zagrożenie bezpieczeństwa. Zobacz, dlaczego tak jest. domyślnie nie na ścieżce? na Superuser, dlaczego.
Możliwe jest dodanie bieżącego katalogu do PATH, ale z powodów podanych w łączonym pytaniu nie poleciłbym tego.
.
do PATH
(jak sugerują obecnie 2 odpowiedzi) ze względu na ryzyko bezpieczeństwa wspomniane w tej odpowiedzi.
.
, możesz użyć pełnej lub względnej ścieżki do pliku wykonywalnego, np. /home/user/foo/a.out
Lub./build/a.out
.
jest wyjątkowy, ponieważ oznacza „mój bieżący katalog”, więc może to być dowolny katalog, w którym użytkownik znajdzie go z uprawnieniami do odczytu i wykonywania. Jest to potencjalnie bardziej niebezpieczne niż dodanie określonej w pełni kwalifikowanej ścieżki.
.
nie ma specjalnego statusu, jest to ścieżka, która równie dobrze mogłaby zacząć od /
i ./blah
działałaby równie dobrze z cat
lub grep
jako zachęta do basha.
Powód tego jest prosty.
Załóżmy, że w bieżącym katalogu masz polecenie o tej samej nazwie co aplikacja. Następnie uruchomienie polecenia w powłoce spowoduje wywołanie aplikacji zamiast wbudowanego polecenia. Byłoby to zagrożenie bezpieczeństwa, jeśli nic więcej.
Wymagając ./
użycia z przodu, powłoka wie, że chcesz uruchomić aplikację o podanej nazwie, a nie wbudowane polecenie o tej nazwie.
./
wykonuje pliki, których nie ma w twoim $PATH
, raczej wykonuje plik w bieżącym katalogu (lub innym przez ./home/stefano/script.sh
). Teraz PATH jest zmienną środowiskową, która zawiera wszystkie miejsca, w których bash może szukać programów wykonywalnych, bez pełnej (absolutnej) ścieżki do nich.
Ta separacja jest potrzebna, aby uniknąć uruchomienia niewłaściwego pliku. To znaczy, jeśli masz plik wywoływany ls
w katalogu domowym, nie ma go w ŚCIEŻCE, dzięki czemu bash nie pomyli go z rzeczywistym ls
. Zmienna PATH określa również kolejność wyszukiwania:
exec
systemowe (specjalna metoda jądra, sposób uruchamiania programów), system szuka pliku, przechodząc przez każdy z katalogów w zmiennej PATH. Po znalezieniu programu, nawet jeśli znajduje się on w wielu katalogach, wyszukiwanie jest przerywane i uruchamiany jest pierwszy znaleziony.Aby uruchomić plik, musisz ustawić bit wykonywalny w uprawnieniach:
Ponieważ jesteś już w wierszu poleceń, możesz po prostu pisać chmod +x finename
.
Lub możesz ustawić uprawnienia, klikając plik prawym przyciskiem myszy i wybierając Właściwości :
Możesz teraz skopiować plik do dowolnego katalogu w PATH, aby zobaczyć, które z nich istnieją - i są ustawione dla poszczególnych użytkowników - typu echo $PATH
.
stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Jeśli utworzysz plik wykonywalny cat
i przeniesiesz go /usr/local/sbin
, zostanie on uruchomiony zamiast właściwego cat
, który znajduje się w /bin
. Możesz dowiedzieć się, gdzie są twoje pliki, używając type cat
i whereis cat
.
gcc
, co automatycznie ustawia bit wykonania.
./
przed uruchomieniem programu?W terminalu, za każdym razem, gdy wpiszesz nazwę aplikacji, powiedzmy gedit
, terminal przejdzie do niektórych (wstępnie zdefiniowanych) katalogów zawierających aplikacje (pliki binarne aplikacji). Nazwy tych katalogów są zawarte w zmiennej o nazwie PATH
. Możesz zobaczyć, co jest w tej zmiennej, wykonując echo $PATH
. Widzisz te katalogi oddzielone :
? Są to katalogi, że terminal będzie go przeszukania, jeśli tylko wpisać gedit
, nautilus
albo a.out
. Jak widać, ścieżka twojego a.out
programu nie istnieje. Kiedy to zrobisz ./a.out
, mówisz terminalowi: „zajrzyj do bieżącego katalogu, uruchom a.out
i nie wchodź do środka PATH
.
Jeśli nie chcesz pisać za ./
każdym razem, musisz dodać a.out
katalog $PATH
. W poniższych instrukcjach założę, że ścieżka a.out
jest /path/to/programs/
, ale powinieneś zmienić ją na swoją rzeczywistą ścieżkę.
Po prostu dodaj następujący wiersz na końcu pliku ~/.pam_environment
:
PATH DEFAULT=${PATH}:/path/to/programs
Źródło: Trwałe zmienne środowiskowe
Wyloguj się i zaloguj ponownie. Teraz będziesz mógł uruchomić a.out
bez ./
żadnego katalogu.
Jeśli masz inne programy w innych katalogach, możesz po prostu dodać je do powyższej linii. Jednak radzę mieć na przykład jeden katalog o nazwie „myPrograms” i umieścić pod nim wszystkie swoje programy.
Uwaga: zmień
userName
na swoją rzeczywistą nazwę użytkownika Ubuntu.
Co jeśli masz inne programy, które chcesz uruchomić? I wszystkie są w różnych folderach? Cóż, „bardziej zorganizowanym” rozwiązaniem byłoby utworzenie folderu o nazwie bin
pod twoim katalogiem domowym i dodanie do niego dowiązań symbolicznych (skrótów). Oto jak:
mkdir /home/userName/bin
bin
w katalogu głównym .ln -s /path/to/programs/a.out /home/userName/bin
a.out
programu pod bin
.Wyloguj się i zaloguj ponownie. Teraz będziesz mógł uruchomić a.out
bez ./
żadnego katalogu.
Teraz, gdy masz inny program gdziekolwiek indziej, powiedzmy, że program b.in
na pulpicie, wszystko, co musisz zrobić, to: ln -s /home/userName/Desktop/b.in /home/userName/bin
a wtedy będziesz mógł go uruchomić również bez niego ./
.
Uwaga: dzięki komentarzowi @ Joe podczas wykonywania kopii zapasowych linki symboliczne muszą być obsługiwane w specjalny sposób. Domyślnie
rsync
wcale ich nie przetwarza, więc po przywróceniu ich nie ma.
Jak zauważył George w swojej odpowiedzi, pomaga to zauważyć, że wykonujesz plik w bieżącym katalogu roboczym ( pwd
).
Pamiętam, jak dawno temu zadawałem to pytanie mojemu seniorowi, powiedział, że powinienem dodać .
do mojej ścieżki, aby kiedy to zrobiłem a.out
, zajrzał do bieżącego katalogu i wykonał to. W tym przypadku nie muszę tego robić ./a.out
.
Ale osobiście odradzam to. Nigdy mi się to nie zdarzyło, ale jeśli znajdujesz się w obcym katalogu sieci lub coś takiego, a ls
istnieje tam złośliwy plik wykonywalny o nazwie , to posiadanie .
na swojej drodze jest bardzo złym pomysłem. Nie to, że często napotykasz ten problem, po prostu mówiąc.
.
do $PATH
. Bardzo niebezpieczny pomysł.
Oprócz innych odpowiedzi, tutaj zasadnicza część, z man bash
której dobrze to wyjaśnia:
WYKONANIE POLECEŃ Po podzieleniu polecenia na słowa, jeśli powoduje proste polecenie i opcjonalna lista argumentów, następujące działania to wzięty. Jeśli nazwa polecenia nie zawiera ukośników, powłoka próbuje zlokalizować to. Jeśli istnieje funkcja powłoki o tej nazwie, jest to funkcja wywoływane jak opisano powyżej w FUNKCJACH. Jeśli nazwa nie pasuje do Funkcja szuka powłoki na liście wbudowanych powłok. Jeśli znaleziono dopasowanie, że wbudowane jest wywoływane. Jeśli nazwa nie jest ani funkcją powłoki, ani wbudowanym i nie zawiera ukośniki, bash przeszukuje każdy element ŚCIEŻKI w poszukiwaniu katalogu posiadanie pliku wykonywalnego o tej nazwie.
„./” ma sens, gdy uruchamiasz program, który jest ci znany i konkretny, np. Własny. Ten program musi być obecny w twoim bieżącym katalogu. „./” nie ma sensu, gdy uruchomisz standardowe polecenie, które jest gdzieś w $ PATH. Polecenie „Które polecenie uruchomić” informuje, gdzie znajduje się polecenie uruchomienia w $ PATH.
$ gcc hello.c -o /path/to/someplace/hello
stworzy plik wykonywalny w niektórych lokalizacjach. Jeśli ta lokalizacja znajduje się na Twojej ścieżce, będziesz mógł uruchomić plik. Możesz to zrobić, jeśli chcesz utworzyć etykietę dla akcji „skompiluj ten kod źródłowy za pomocą gcc i umieść plik wykonywalny w miejscu, które znajduje się na twojej ścieżce”
Sugerowałbym utworzenie nowego katalogu o nazwie „testbin” lub coś w tym rodzaju i umieszczenie go na swojej ścieżce, aby utrzymać istniejące katalogi ścieżek w czystości.
./
eliminuje zbędne wyszukiwanie ścieżki. ./
wymusza wyszukiwanie tylko w bieżącym katalogu. Jeśli nie dajemy ./
wtedy będzie wyszukiwać różne ścieżki ustawione w systemie jak /usr/bin
, /usr/sbin/
itp
„./” oznacza, że chcesz uruchomić plik w bieżącym katalogu, jest to skrót do wpisania całej ścieżki, na przykład:
[root@server ~]#/path/to/file/file.pl
jest taki sam jak:
[root@server file]#./file.pl
w poprzednim przykładzie przejrzałeś katalog i jego podkatalogi do lokalizacji pliku i użyłeś „./”, aby uruchomić plik w bieżącym katalogu.
poprzedni „ [root @ server ~] # / path / to / file / file.pl ” również wykona plik, jeśli leniwy jest „cd” w drodze do lokalizacji pliku.
To bardzo proste i ma wiele zastosowań.
/usr/bin
. Na przykład Python 2.7, Python 2.6 jest zainstalowany, ale / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6Jeśli znajdujesz się na ścieżce /usr/local/bin
i uruchamia się Python, zawsze wykona Python 2.7. Określenie .
zajmie plik wykonywalny bieżącego folderu.
.
- zawsze reprezentuje wykonanie z bieżącego katalogu. I ..
zawsze oznacza wykonanie z poprzedniego katalogu.