Varför använder vi ./filename
för att köra en fil i Linux?
Varför inte skriv bara in det som andra kommandon gcc
, ls
etc …
Kommentarer
- Skulle ’ inte den första raden skrivas bättre som ” Varför använder vi
./command_name
för att utföra ett kommando i Linux? ” - user15760, Nej, för vi vill att frågor ska ställas upptäcks i sökmotorer och inte alla som har den här frågan är naturligt född ’ nixsters (:
Svar
I Linux, UNIX och relaterade operativsystem anger .
den aktuella katalogen. Eftersom du vill köra en fil i din nuvarande katalog och den katalogen finns inte i din $PATH
, du behöver ./
-biten för att berätta för skalet var den körbara är. Så, ./foo
betyder att kör den körbara filen som heter foo
som finns i den här katalogen.
Du kan använda type
eller which
för att få hela sökvägen för alla kommandon som finns i dina $PATH
.
Kommentarer
Svar
Om du menar, varför behöver du det./ i början – det beror på att (till skillnad från Windows), den aktuella katalogen inte är en del av din sökväg som standard. Om du kör:
$ ls
ditt skal letar efter ls
i katalogerna i din PATH-miljövariabel (echo $PATH
för att se det), och kör den första körningen som heter ls
som den hittar. Om du skriver:
$ a.out
kommer skalet att göra samma sak – men det kommer förmodligen inte att hitta en körbar som heter a.out. Du måste berätta för skalet var a.out är – det är i den aktuella katalogen (.) så är sökvägen ./a.out
.
Om du frågar varför det heter ”a.out”, det är bara standardutdatafilnamnet för gcc. Du kan ändra det med -o-kommandoraden arg. Till exempel:
$ gcc test.c -o test $ ./test
Kommentarer
- Tack. Mitt tvivel är varför behöver du ./ i början …. Jag fick använda ”” (för att visa den aktuella katalogen) men varför ” / ” efter det?
- / är banavskiljaren i Linux, så du använder den för att separera katalogen (.) från filnamnet (a.out). Utan den har du .a.out som är giltigt filnamn i sig. (Testa
touch .a.out; ls -lA
för att se detta.) - det är så du anger sökväg i Unix,
<dir>/<file>
så du säger i princip exekvera en fil i den aktuella katalogen, vilket indikeras av./test
- Red Hat Linux 9? Dags att uppgradera!
- I Windows 10 är PowerShell standardskalet nu, och det kräver också
./
för att köra en körbar i den aktuella sökvägen
Svar
Du kan försöka lägga till :.
till din $ PATH-variabel.
Försök med ALT + F2 och skriv: gksudo gedit /etc/environment
om du kör Linux / GTK (det här är vad du har om du använder Ubuntu).
Dock, Jag rekommenderar starkt att du INTE gör det. Det är dåligt dåligt dåligt och dåligt.
Du vet, den typen av saker fungerar så här sedan 1970. Det finns en anledning till att den aktuella katalogen inte ingår i $ PATH.
.
är den aktuella katalogen
.something
skulle vara en dold fil (typ ”ALT +” för att skapa dem visas i Nautilus, eller försök ”ls -la
”.
./someProgram.sh
är det du skriver för att KÖRA ett körbart program .sh i den aktuella katalogen.
.somethingElse
skulle innebära att du har en dold körbar i den aktuella katalogen, vilket är en dålig idé.
Svar
Den mer fullständiga regeln är faktiskt: om någon snedstreck /
är i sökvägen, sök inte PATH
Innan vi går in motiveringen, bör du först veta om detta faktum: kör någon av:
bin/someprog
eller:
eller:
cd bin ./myexec
kör bin/someprog
utan att söka i PATH
variabel av exakt samma anledning: alla bin/someprog
, /bin/someprog
och ./someprog
har en snedstreck /
i sig.
someprog
ensam har inte snedstreck /
och söker därför bara i PATH
.
POSIX 7 specificerar denna regel vid: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
PATH
[…] Om sökvägen till sökvägen innehåller en
<slash>
ska sökningen genom sökprefixen inte utföras .
Motiv för /
POSIX PATH-regel
Antag att körning:
someprog
skulle söka:
- relativt CWD först
- relativt PATH efter
Då, om du ville springa /bin/someprog
från din distro, och du gjorde:
someprog
det skulle ibland fungera, men andra skulle det misslyckas, för du kanske befinner dig i en katalog som innehåller ett annat icke-relaterat someprog
-program.
Därför skulle du snart få veta att detta inte är tillförlitligt och du skulle sluta alltid använda absoluta vägar när du vill använda PATH, och därmed besegra syftet med PATH.
Det är också därför att ha relativa vägar i din PATH är en riktigt dålig idé. Jag ”m tittar på dig, node_modules/bin
.
Omvänt, antar att körning:
./someprog
Skulle söka:
- relativt PATH först
- i förhållande till CWD efter
Sedan, om du precis laddat ner ett skript someprog
från ett git-arkiv och ville köra det från CWD, skulle du aldrig vara säker på att det här är det faktiska programmet som skulle köras, för kanske har din distro en:
/bin/someprog
som finns i dig PATH från något paket som du installerade efter att ha druckit för mycket efter jul förra året.
Därför skulle du än en gång tvingas att alltid köra lokala skript i förhållande till CWD med fullständiga banor för att veta vad du kör:
"$(pwd)/someprog"
vilket också skulle vara extremt irriterande.
En annan regel som du kan vara frestad att komma på är:
relativa sökvägar använder endast PATH, endast absoluta banor CWD
men återigen tvingar detta användare att använd alltid abso lutvägar för icke-PATH-skript med "$(pwd)/someprog"
.
/
söksökningsregeln erbjuder en enkel att komma ihåg lösningen till problemet:
- snedstreck: använd inte
PATH
- inget snedstreck: använd endast
PATH
vilket gör det super lätt att alltid veta vad du kör, genom att förlita sig på att filer i den aktuella katalogen kan uttryckas antingen som ./somefile
eller somefile
, så det ger en av dem speciell betydelse.
Ibland är det lite irriterande att du inte kan söka för some/prog
i förhållande till PATH
, men jag ser inte en bättre lösning på detta.
alias
es som kan komma i vägen, inte bara$PATH
..
först skulle det vara ett säkerhetsproblem, du eller någon annan kan ersättals
till exempel (ett enkelt virus / trojen: skapa en zip-fil med en körbar namn som heterls
, som någon söker igenom, de kör den här körbara filen, att …). Om det sökte.
senast kan du spendera lång tid på att bli galen utan att veta varför ditt program inte fungerar (t.ex. gör du ett program som heter test, istället för att köra ditt program körs det systemtestprogrammet. Vilket ger ingen utdata).Det bokstavliga svaret är som andra har gett: eftersom den aktuella katalogen inte finns i din
$PATH
.Men varför? Kort sagt, det är för säkerhet. Om du söker i någon annans hemkatalog (eller / tmp) och bara skriver
gcc
ellerls
vill du vet att du kör den riktiga, inte en skadlig version som din prankster-vän har skrivit som raderar alla dina filer. Ett annat exempel skulle varatest
eller[
, som kan åsidosätta dessa kommandon i skalskript, om ditt skal inte har de som inbyggda.Att ha
.
som senaste inträde i din väg är lite säkrare, men det finns andra attacker som använder det. En lätt är att utnyttja vanliga skrivfel, somsl
ellerls-l
. Eller hitta ett vanligt kommando som råkar inte vara installerat på det här systemet –vim
, till exempel eftersom sysadmins är sannolikt över genomsnittet att skriva det.Låter det här för teoretiskt? Det är till stor del , men det kan definitivt hända i verkligheten, särskilt på fleranvändarsystem. Faktum är att här är ett exempel från den här webbplatsen där en administratör bytte till en användares ”hemkatalog och hittade
ps
att maskeras av en körbar med det namnet.Kommentarer
PATH
miljövariabel.