Lær å bruke Linux `which` kommando: Finn riktig programfil!


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.