Forståelse av Linux «which»-kommandoen
I Linux-systemer spiller kommandoen «which» en sentral rolle for å lokalisere den eksakte binære filen som blir aktivert når du kjører en kommando i terminalen. Denne funksjonen er spesielt nyttig når det finnes flere versjoner av samme program på datamaskinen, da den hjelper til med å identifisere hvilken av dem som blir benyttet.
Binærfiler og baner
Når du ber om å utføre et program eller en kommando fra terminalen, må skallet (ofte Bash i moderne Linux-distribusjoner) finne og starte den aktuelle kommandoen. Enkelte kommandoer, som for eksempel cd, history og pwd, er integrerte i selve skallet. Derfor trenger Bash ikke å lete etter disse.
Hvordan finner derimot Bash andre kommandoer, programmer og eksterne, frittstående binærfiler? Svaret ligger i «banen» (PATH), som er en liste over kataloger. Bash søker systematisk gjennom disse katalogene etter en kjørbar fil som matcher kommandoen eller programmet du forsøker å kjøre. Når en match er funnet, starter Bash filen og avbryter søket.
Du kan inspisere miljøvariabelen $PATH
for å se hvilke kataloger som inngår i din bane. Dette gjøres ved å skrive følgende i terminalen:
echo $PATH
I utskriften er banene adskilt med kolon (:). På vårt system vil Bash søke i følgende kataloger i denne rekkefølgen:
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
Det finnes flere mapper med navn som /sbin
og /bin
i filsystemet, noe som av og til kan skape litt forvirring.
Eksempel på bruk av baner
La oss anta at vi har en oppdatert utgave av programmet htg
. Denne versjonen er plassert i vår gjeldende mappe, og kan startes ved å skrive kommandoen:
./htg
Dette programmet er enkelt; det viser bare versjonsnummeret (1.2.138) og avsluttes. For å kjøre et program som ligger i den nåværende mappen, kreves ./
foran programnavnet, slik at Bash vet hvor den skal lete.
For å kunne kjøre programmet fra hvilken som helst mappe, vil vi flytte den kjørbar filen til /usr/bin
-mappen. Da vil Bash finne programmet i banen og utføre det.
Etter å ha flyttet filen, trenger vi ikke lenger å bruke ./
foran programnavnet. Vi kan utføre dette ved hjelp av kommandoen nedenfor:
sudo mv htg /usr/bin
La oss forsøke å starte programmet igjen ved å skrive:
htg
Det viser seg at noe kjører, men det er ikke vår oppdaterte versjon. Det er den eldre utgaven, 1.2.105.
Bruken av «which»-kommandoen
Det er her kommandoen «which» kommer inn i bildet. Den ble laget for å håndtere akkurat slike situasjoner.
I dette eksemplet bruker vi «which» og sender inn programnavnet som en kommandolinjeparameter:
which htg
Dette viser at en versjon av htg
ble funnet i /usr/local/bin
-mappen. Siden denne plasseringen prioriteres i banen før mappen der vi flyttet den oppdaterte versjonen, velger Bash den gamle versjonen av programmet.
Hvis vi derimot benytter oss av «-a»-flagget (alle), som fortsetter søket selv om en match er funnet:
which -a htg
Da vises alle forekomster av programmet som finnes i banen.
Problemet er at det eksisterer en eldre versjon av programmet i en mappe som også ligger i oppdateringsbanen, og som blir søkt før mappen der den nye versjonen ligger.
Vi kan verifisere dette ved å eksplisitt starte hver versjon:
/usr/local/bin/htg
/usr/bin/htg
Dette forklarer problemet, og løsningen er relativt enkel. Vi kan enten fjerne den eldre versjonen fra /usr/local/bin
-mappen eller flytte den fra /usr/bin
til /usr/local/bin
.
Forståelse av resultater
Det er viktig å vite at to resultater ikke nødvendigvis innebærer to forskjellige binærfiler.
La oss se på et eksempel der vi bruker «which»-kommandoen med «-a»-flagget for å finne versjoner av programmet less
:
which -a less
Dette viser to steder der less
angivelig finnes, men stemmer dette? Det ville vært merkelig å ha to ulike (eller identiske på forskjellige steder) versjoner av less
installert på samme Linux-maskin. Derfor undersøker vi dette nærmere.
Vi bruker kommandoen ls
med flaggene -l
(lang liste) og -h
(human-readable) for å analysere situasjonen:
ls -lh /usr/bin/less
Filstørrelsen er oppgitt til ni byte! Dette kan umulig være en fullstendig kopi av less
.
Det første tegnet i oppføringen er en «l». En vanlig fil vil ha en bindestrek (-) som første tegn. Bokstaven «l» signaliserer en symbolsk lenke. «->» indikerer også at det er en symbolsk lenke, som kan oppfattes som en snarvei. Denne lenken peker til kopien av less
i /bin
-mappen.
La oss prøve igjen med versjonen av less
i /bin
:
ls -lh /bin/less
Dette ser derimot ut som en ekte binærfil. Det første tegnet er en bindestrek, og filstørrelsen er på 167 KB. Konklusjonen er at kun en kopi av less
er installert, men det finnes en symbolsk lenke til den fra en annen mappe, som Bash også finner når den søker i banen.
Sjekke flere kommandoer
Du kan sende inn flere programmer og kommandoer til «which». Den vil da sjekke dem etter tur.
For eksempel:
which ping cat uptime date head
Dette vil generere et resultat for hver av programmene og kommandoene du har listet opp.
Hvor «which» selv ligger
Om du ønsker, kan du også benytte kommandoen «which» på selve kommandoen ved å skrive følgende:
which which
Foruten å utforske Linux-filsystemet, er which
mest nyttig når du opplever uventet atferd fra en kommando eller et program. Ved å bruke «which» kan du bekrefte at kommandoen Bash starter er den du forventer å bruke.