Waarom gebruiken we ./filename
om een bestand in linux uit te voeren?
Waarom niet voer het gewoon in zoals andere commandos gcc
, ls
etc …
Opmerkingen
Antwoord
In Linux, UNIX en gerelateerde besturingssystemen geeft .
de huidige directory aan. Omdat je een bestand in je huidige directory en die directory wilt draaien staat niet in je $PATH
, je hebt het ./
-bit nodig om de shell te vertellen waar het uitvoerbare bestand is. Dus ./foo
betekent dat u het uitvoerbare bestand foo
uitvoert dat zich in deze map bevindt.
U kunt type
of which
om het volledige pad op te halen van alle commandos gevonden in uw $PATH
.
Opmerkingen
- Het is heel gebruikelijk om programmas uit te voeren in de huidige directory. Waarom zoekt de shell daar ook niet ‘? Het zoekt eerst in., Dan in $ PATH.
- Er zijn ook
alias
-es die in de weg kunnen staan, niet alleen$PATH
. - @Michael veiligheid en gezond verstand: als het eerst in
.
zocht, dan zou het een beveiligingsprobleem zijn, zou u of iemand anders kunnen vervangenls
bijvoorbeeld (een eenvoudig virus / trojen: maak een zip-bestand met een uitvoerbaar bestand met de naamls
erin, terwijl iemand doorzoekt, ze draaien dit uitvoerbare bestand, dat …). Als het als laatste heeft gezocht in.
, dan kun je een lange tijd gek worden zonder te weten waarom je programma niet werkt (je maakt bijvoorbeeld een programma met de naam test, in plaats van je programma uit te voeren, draait het het systeemtestprogramma. Dat levert geen output op). - @jcubic dat ‘ een slecht idee is. Zie de opmerking hierboven. In het verleden zocht DOS in de huidige directory en dat gedrag werd overgedragen op Windows cmd, wat veel beveiligingsproblemen introduceerde. MS heeft dat opgelost in PowerShell en nu moet je. \ Gebruiken om het programma in de huidige directory uit te voeren
- @ ctrl-alt-delor: Toen ik eind jaren 80 op de universiteit zat ‘ s, dit was een veel voorkomende (verboden) tactiek. Een ” ls ” programma schrijven en het in je thuismap laten staan voor het geval iemand anders komt rondneuzen. Het programma heette een ” get shell ” IIRC. Het zou proberen de inloggegevens te achterhalen van de gebruiker die het commando uitvoert – en dan misschien een nep-directorylijst afdrukken om ze niet op de hoogte te laten.
Answer
Het letterlijke antwoord is zoals anderen hebben gegeven: omdat de huidige directory niet “t in uw $PATH
staat.
Maar waarom? Kortom, het is voor de veiligheid. Als u in de homedirectory van iemand anders (of / tmp) zoekt en alleen gcc
of ls
typt, wilt u weet dat je de echte versie gebruikt, niet een kwaadaardige versie die je grappenmaker heeft geschreven en die al je bestanden wist. Een ander voorbeeld is test
of [
, die deze commandos in shell-scripts zou kunnen overschrijven, als je shell die niet heeft als ingebouwde.
.
als de laatste invoer op uw pad is een beetje veiliger, maar er zijn andere aanvallen die hiervan gebruik maken. Een gemakkelijke manier is om veelvoorkomende typefouten te misbruiken, zoals sl
of ls-l
. Of zoek een veelvoorkomend commando dat toevallig niet op dit systeem is geïnstalleerd – vim
, bijvoorbeeld, aangezien sysadmins een bovengemiddelde kans hebben om dat te typen.
Klinkt dit te theoretisch? Het is grotendeels , maar het kan in werkelijkheid zeker gebeuren, vooral op systemen met meerdere gebruikers. In feite is hier een voorbeeld van deze site waar een beheerder overschakelde naar de homedirectory van een gebruiker en ps
vond worden gemaskeerd door een uitvoerbaar bestand met die naam.
Opmerkingen
- Gebruik alleen absolute paden in de
PATH
omgevingsvariabele.
Antwoord
Als je bedoelt, waarom heb je./ aan het begin – dat komt omdat (in tegenstelling tot Windows) de huidige directory standaard geen deel uitmaakt van je pad. Als je:
$ ls
uitvoert, zoekt je shell naar ls
in de mappen in je PATH-omgevingsvariabele (echo $PATH
om het te zien), en draait het eerste uitvoerbare bestand genaamd ls
dat het vindt. Als je typt:
$ a.out
zal de shell hetzelfde doen – maar het zal waarschijnlijk “geen uitvoerbaar bestand vinden met de naam a.out. Je moet de shell vertellen waar a.out is – het staat in de huidige directory (.) dan is het pad ./a.out
.
Als je vraagt waarom het heet “a.out”, dat “is gewoon de standaard uitvoerbestandsnaam voor gcc. Je kunt het wijzigen met de -o opdrachtregel arg. Bijvoorbeeld:
$ gcc test.c -o test $ ./test
Reacties
- Bedankt. Mijn twijfel is waarom je ./ aan het begin nodig hebt … Ik heb het gebruik van “.” (om de huidige directory te bekijken) maar waarom ” / ” daarna?
- / is het padscheidingsteken in Linux, dus je gebruikt het om de directory (.) te scheiden van de bestandsnaam (a.out). Zonder dit heb je .a.out wat een geldige bestandsnaam op zich. (Probeer
touch .a.out; ls -lA
om dit te zien.) - zo specificeer je de pad in Unix,
<dir>/<file>
dus je zegt eigenlijk: voer een bestand uit in de huidige directory, wat wordt aangegeven door./test
- Red Hat Linux 9? Tijd om te upgraden!
- Op Windows 10 is PowerShell nu de standaardshell en het vereist ook
./
om een uitvoerbaar bestand in het huidige pad uit te voeren
Antwoord
U kunt proberen :.
toe te voegen aan uw $ PATH-variabele.
Probeer ALT + F2 en typ: gksudo gedit /etc/environment
als Linux / GTK draait (dit is wat je hebt als je Ubuntu gebruikt).
ECHTER, Ik raad u ten zeerste aan om dat NIET te doen. Het is erg slecht slecht en slecht.
Weet je, dat soort dingen werken zo sinds 1970. Er is een reden waarom de huidige directory niet is opgenomen in $ PATH.
.
is de huidige directory
.something
zou een verborgen bestand zijn (typ “ALT +” om ze verschijnen in Nautilus, of probeer “ls -la
“.
./someProgram.sh
is wat je typt om een uitvoerbaar programma uit te voeren .sh in de huidige directory.
.somethingElse
zou betekenen dat je een verborgen uitvoerbaar bestand in de huidige directory hebt, wat een slecht idee is.
Answer
De meer volledige regel is eigenlijk: if any slash /
staat in het pad, zoek niet PATH
Voordat we ingaan op de grondgedachte, zou u eerst dit feit moeten weten: het uitvoeren van een van:
bin/someprog
of:
of:
cd bin ./myexec
voer bin/someprog
uit zonder het PATH
variabele om exact dezelfde reden: alle bin/someprog
, /bin/someprog
en ./someprog
bevatten een schuine streep /
.
someprog
alleen heeft geen schuine streep /
, en zoekt daarom alleen in PATH
.
POSIX 7 specificeert deze regel op: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
PATH
[…] Als de padnaam die wordt gezocht een
<slash>
bevat, zal het zoeken via de padvoorvoegsels niet worden uitgevoerd .
Rationale voor de /
POSIX PATH-regel
Stel dat hardlopen:
someprog
zou zoeken:
- eerst relatief ten opzichte van CWD
- ten opzichte van PATH na
Vervolgens, als je /bin/someprog
vanuit je distro, en dat deed je:
someprog
het werkte soms, maar bij andere mislukte het, omdat je bevindt je misschien in een directory die een ander niet-gerelateerd someprog
programma bevat.
Daarom zou je snel leren dat dit niet betrouwbaar is, en zou je uiteindelijk altijd absolute paden als je PATH wilt gebruiken, en daarmee het doel van PATH tenietdoet.
Dit is ook waarom het hebben van relatieve paden in je PATH een heel slecht idee is. Ik “m kijk naar jou, node_modules/bin
.
Omgekeerd, stel dat het uitvoeren van:
./someprog
eerst zou zoeken:
- relatief aan PATH
- ten opzichte van CWD na
Dan, als je zojuist een script someprog
uit een git-repository hebt gedownload en het wilde uitvoeren van CWD, zou je nooit zeker weten dat dit het daadwerkelijke programma is dat zou draaien, want misschien heeft je distro een:
/bin/someprog
die in je PATH van een pakket dat je installeerde nadat je vorig jaar na Kerstmis te veel had gedronken.
Daarom zou je opnieuw gedwongen worden om altijd lokale scripts uit te voeren ten opzichte van CWD met volledige paden om te weten wat je gebruikt:
"$(pwd)/someprog"
wat ook buitengewoon vervelend zou zijn.
Een andere regel die je zou kunnen bedenken, is:
relatieve paden gebruiken alleen PATH, absolute paden alleen CWD
maar nogmaals, dit dwingt gebruikers om gebruik altijd abso luitpaden voor niet-PATH-scripts met "$(pwd)/someprog"
.
De /
zoekregel voor paden biedt een eenvoudig te onthouden oplossing naar het probleem:
- slash: gebruik niet
PATH
- geen slash: gebruik alleen
PATH
wat het supergemakkelijk maakt om altijd te weten wat u draait, door erop te vertrouwen dat bestanden in de huidige directory kunnen worden uitgedrukt als ./somefile
of somefile
, en dus geeft het een speciale betekenis aan een van hen.
Soms is het een beetje vervelend dat je niet kunt zoeken voor some/prog
ten opzichte van PATH
, maar ik zie geen betere oplossing hiervoor.
./command_name
om een commando in linux uit te voeren? ”