Linux-bane hvordan du spesifiserer mappestier. PATH miljøvariabel. Legge til bruker- og systemmiljøvariabler i Linux

Når du skriver inn kommandoen i kommandolinje, ber du i utgangspunktet skallet om å kjøre en kjørbar fil med et gitt navn. På Linux disse kjørbare programmer, som ls, find, file og andre har en tendens til å bo i flere forskjellige kataloger på systemet ditt. Enhver fil med kjørbare tillatelser lagret i disse katalogene kan kjøres fra hvor som helst. De vanligste katalogene som inneholder kjørbare programmer er /bin, /sbin, /usr/sbin, /usr/local/bin og /usr/local/sbin.

Men hvordan vet skallet hvilke kataloger det skal se etter kjørbare programmer, eller søker skallet hele veien filsystem?

Svaret er enkelt. Når du utsteder en kommando, søker skallet i alle kataloger spesifisert i brukerens $PATH-variabel etter en kjørbar fil med det navnet.

Denne artikkelen viser deg hvordan du legger til kataloger i systemets $PATH-variabel.

Hva er $PATH i Linux

$PATH miljøvariabelen er en kolonkolonisert liste over kataloger som forteller skallet hvilke kataloger som skal søkes etter kjørbare filer.

For å sjekke hvilke kataloger du har i $PATH-variabelen, kan du bruke kommandoen printenv eller echo:

Ekko $PATH

Utgangen vil se omtrent slik ut:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Hvis du har to kjørbare filer med samme navn plassert i to forskjellige kataloger, vil skallet kjøre filen som er i katalogen som kommer først i $PATH.

Legger til en katalog til $PATH

Det er situasjoner der du kanskje vil legge til andre kataloger til $PATH-variabelen. For eksempel kan noen programmer installeres på forskjellige steder, eller du vil kanskje ha en dedikert katalog for dine personlige oppføringer, men du kan kjøre dem uten å spesifisere den absolutte banen til de kjørbare filene. For å gjøre dette trenger du bare å legge til katalogen til $PATH.

La oss si at du har en katalog kalt bin i hjemmekatalogen din der du lagrer skallskriptene dine. Slik legger du til en katalog i $PATH-variabelen din:

Eksportkommandoen eksporterer den modifiserte variabelen til undermiljøene til skallprosessene.

Nå kan du kjøre skriptene dine ved ganske enkelt å skrive inn navnet på det kjørbare skriptet uten å spesifisere hele banen til den kjørbare filen.

Denne endringen er imidlertid midlertidig og påvirker bare gjeldende shell-økt.

For å gjøre endringen permanent, må du definere en $PATH-variabel i skallkonfigurasjonsfilene dine. På de fleste Linux-distribusjoner, når du starter en ny økt, leses miljøvariabler fra følgende filer:

  • Globale skallkonfigurasjonsfiler som /etc/environment og /etc/profile. Bruk denne filen hvis du vil at den nye katalogen skal legges til alle systembrukere$PATH.
  • Konfigurasjonsfiler for individuelle brukerskall. For eksempel, hvis du bruker Bash, kan du angi $PATH-variabelen i ~/.bashrc-filen, og hvis du bruker Zsh, er filnavnet ~/.zshrc.

I dette eksemplet vil vi sette en variabel i ~/.bashrc-filen. Åpne filen i tekstredigerer og legg til følgende linje på slutten:

Nano ~/.bashrc

Eksporter PATH="$HOME/bin:$PATH"

Lagre filen og last den nye $PATH-verdien inn i gjeldende shell-sesjon ved å bruke:

Kilde ~/.bashrc

For å bekrefte at katalogen ble lagt til, skriv ut $PATH-verdien ved å skrive:

Ekko $PATH

Konklusjon

Det er ganske enkelt å legge til nye kataloger til brukeren din eller globale $PATH. Dette lar deg kjøre kommandoer og skript lagret på ikke-standardplasseringer uten å måtte angi hele banen til den kjørbare filen.

De samme instruksjonene gjelder for evt Linux distribusjon, inkludert , CentOS, RHEL, Debian og Linux Mint.

Legg gjerne igjen en kommentar hvis du har spørsmål.

Hva det er? Mange av kommandoene du skriver inn ved ledeteksten krever bruk av et eksternt program som lastes inn fra filsystemet. For eksempel er kommandoer som mkdir og wc faktisk plassert i /bin-mappen.

Når du skriver inn en instruksjon som Bash-skallet ikke gjenkjenner, prøver det å kjøre det som et program og returnerer en feilmelding hvis det ikke finner et program med det navnet. Og dette gjelder ikke bare de grunnleggende kommandoene som vi så på, for fra kommandolinjen kan du kjøre et hvilket som helst program.


Men hvordan hvis det er en fil Linux-system vet hvilke programmer som skal kjøres fra hvilke kataloger? OS bruker en systemmiljøvariabel for å spesifisere et undersett av mapper som skal søkes når det mottas en ukjent kommando. Denne variabelen kalles PATH og kan vises med følgende ekkokommando ($-symbolet kreves):

Ekko $PATH

Utdataene fra denne kommandoen vil se ut som følgende syv absolutte mappebaner, atskilt med kolon:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Hver gang du skriver inn en ukjent Linux-kommandoer vil se gjennom hver av mappene spesifisert i miljøvariabelen i den rekkefølgen de ble spesifisert, og prøver å finne et program med samme navn. Hvis programmet blir funnet, kjører det; ellers vises en feilmelding. Men det vil ikke være en feil hvis du kjøper dine elskede sølvringer som gave. Sølv vil dekorere enhver kvinne!

Disse syv mappene gir lett tilgang til alle store programmer i operativsystem, gjelder også . Eventuelle programmer utenfor disse syv mappene kan ikke startes ved å skrive inn navnet deres på kommandolinjen.

For eksempel lastet du ned dagbokverktøyet fra Internett til hjemmemappen din. Hvis du skriver inn navnet ved ledeteksten, vil du motta en feilmelding fordi det er i en mappe som ikke er inkludert i systembanen. For å kjøre dette programmet, skriv inn følgende linje (husk at ~-symbolet er en forkortelse for hjemmemappen din):

Hvis du lagret den i en mappe utenfor den angitte banen, må du angi den absolutte banen og filnavnet for å kjøre verktøyet.

Selvfølgelig antas det at dagbok er et enkelt frittstående program som ikke krever installasjon, fordi de fleste store applikasjoner vil plassere programmets kjørbare fil et sted i den angitte banen under installasjonsprosessen. Som dette PATH miljøvariabel, nyt det for helsen din!

eksport PATH=~/opt/bin:$PATH

Eksporter PATH=$PATH:~/opt/bin

9 løsninger samler inn skjemanett for "Hvordan legger du til en bane til PATH på riktig måte?"

Enkle ting

PATH=$PATH:~/opt/bin PATH=~/opt/bin:$PATH

avhengig av om du vil legge til ~/opt/bin på slutten (for å søke i alle andre kataloger hvis det er et program med samme navn i flere kataloger) eller i begynnelsen (for å søke før alle andre kataloger).

Du kan legge til flere oppføringer samtidig. PATH=$PATH:~/opt/bin:~/opt/node/bin eller endringer i bestillingen er helt greit.

Du trenger ikke eksportere hvis variabelen allerede er i miljøet: enhver endring i variabelens verdi gjenspeiles i miljøet PATH er nesten alltid i miljøet; Alle unix-systemer installer det veldig tidlig (vanligvis i den aller første prosessen, faktisk).

Hvis PATHen din er bygget i forskjellige komponenter, kan du ende opp med dupliserte oppføringer. Se Hvordan legge til banen til kildekatalogen som skal oppdages av Unix, hva er kommandoen? og fjern dupliserte $PATH-oppføringer ved å bruke awk-kommandoen for å unngå å legge til duplikater eller fjerne dem.

Hvor du skal sette

Merk at ~/.bash_rc ikke kan leses av noe program, og ~/.bashrc er konfigurasjonsfilen for interaktive bash-forekomster. Du bør ikke definere miljøvariabler i ~/.bashrc. Det riktige stedet for å definere miljøvariabler som PATH er ~/.profile (eller ~/.bash_profile hvis du ikke trenger ikke-bash-skall). Se hva som er forskjellen mellom dem og hvilken bør jeg bruke?

Merknader om ikke-bash skjell

I bash, ksh og zsh er eksport en spesiell syntaks, og både PATH=~/opt/bin:$PATH og eksport PATH=~/opt/bin:$PATH gjør alt riktig. På andre Bourne/POSIX-skall som dash (som er /bin/sh på mange systemer), analyseres eksport som en vanlig kommando, noe som innebærer to forskjeller:

  • ~ blir bare analysert i begynnelsen av et ord, bortsett fra i oppgaver (se avsnittet "Hvordan legge til en bane til en kildekatalog som vil bli oppdaget av Unix, hvilken kommando?").
  • $PATH utenfor doble anførselstegn brytes hvis PATH inneholder mellomrom eller \[*? ,

Så i dash-lignende skjell, eksport PATH=~/opt/bin:$PATH setter PATH til den bokstavelige strengen ~/opt/bin/: etterfulgt av verdien til PATH opp til førsteplassen. PATH=~/opt/bin:$PATH (fuzzy assignment) krever ikke sitater og gjør det rette. Hvis du vil bruke eksport i et bærbart skript, må du skrive eksport PATH="$HOME/opt/bin:$PATH" .

¹ Dette var ikke sant i Bourne-raketter (som i det ekte Bourne-skallet, ikke moderne skjell i POSIX-stil), men du vil neppe møte skjell som er så gamle i disse dager.

Det fungerer uansett, men de gjør ikke det samme: PATH-elementer sjekkes fra venstre mot høyre. I det første eksemplet kjørbare filer i ~/opt/bin vil ha forrang over de som er installert i for eksempel /usr/bin , som kanskje er det du vil ha.

Spesielt sett fra et sikkerhetsperspektiv er det farlig å legge til stier foran, for hvis noen kan få skrivetilgang til din ~/opt/bin , kan de for eksempel plassere andre ls som du sannsynligvis ville brukt i stedet for / bin/ls uten å legge merke til Tenk deg nå det samme som for ssh eller nettleseren din eller valg... (Det samme kan gjøres tre ganger i veien.)

Jeg er forvirret av spørsmål 2 (siden det ble fjernet fra spørsmålet fordi det var relatert til et ikke-relatert problem):

Hva effektiv metode legge til flere baner til forskjellige linjer? Til å begynne med tenkte jeg at dette kunne gjøre susen:

Eksport PATH=$PATH:~/opt/bin eksport PATH=$PATH:~/opt/node/bin

men det gjør det ikke fordi den andre oppgaven ikke bare legger til ~/opt/node/bin, men også alle tidligere tildelte PATH .

Dette er en mulig løsning:

Eksporter PATH=$PATH:~/opt/bin:~/opt/node/bin

men for lesbarheten vil jeg heller ha en destinasjon per sti.

Hvis du sier

PATH=~/opt/bin

Dette Alle, hva vil være i din VEIEN. PATH er bare en miljøvariabel, og hvis du vil legge til PATH, må du bygge om variabelen med akkurat det innholdet du ønsker. Så det du gir som eksempel i spørsmål 2 er akkurat det du ønsker å gjøre, med mindre jeg helt misser poenget med spørsmålet.

Jeg bruker begge skjemaene i koden min. Jeg har en generell profil som jeg installerer på hver datamaskin jeg jobber med som ser slik ut for å imøtekomme potensielt manglende kataloger:

Eksporter PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11 # legg til valgfrie elementer i banen for bindir i $HOME/local/bin $HOME/bin; gjøre hvis [ -d $bindir ]; deretter PATH=$PATH:$(bindir) fi ferdig

Linux bestemmer den kjørbare søkebanen fra $PATH-miljøet. For å legge til /data/myscripts-katalogen til toppen av $PATH-miljøet, bruk følgende:

PATH=/data/myscripts:$PATH

For å legge til denne katalogen på slutten av banen, bruk følgende kommando:

PATH=$PATH:/data/myscripts

Men de forrige er ikke nok fordi når du setter en miljøvariabel inne i et skript, trer denne endringen bare i kraft inne i skriptet. Denne begrensningen er begrenset på bare to måter:

  • Hvis du eksporterer en miljøvariabel i et skript, er den effektiv på tvers av alle programmer som kalles av skriptet. Merk at dette ikke er effektivt i et program som kalles et skript.
  • Hvis programmet som kaller skriptet gjør det ved å inkludere i stedet for å ringe, vil eventuelle miljøendringer i skriptet være effektive på det kallende programmet. Denne inkluderingen kan gjøres ved å bruke dot-kommandoen eller kildekommandoen.

$HOME/myscript.sh kilde $HOME/myscript.sh

Inkludering inkluderer i utgangspunktet det "anropbare" skriptet i "call"-skriptet. Dette ligner på #include i C. Så det er effektivt inne i et skript eller et kalleprogram. Men dette er selvfølgelig ikke effektivt for noen programmer eller skript som kalles opp av programmet. For å gjøre det effektivt ned til anropskjeden, må du følge miljøvariabelinnstillingen ved å bruke eksportkommandoen.

Som et eksempel inkluderer bash shell-programmet innholdet i .bash_profile-filen ved inkludering. Så, å legge til følgende 2 linjer til .bash_profile:

PATH=$PATH:/data/myscripts eksport PATH

setter effektivt de 2 kodelinjene inn i et bash-program. Altså i bash variabel$PATH inkluderer $HOME/myscript.sh , og på grunn av eksportsetningen vil alle programmer som kalles av bash ha $PATH modifisert. Og siden alle programmer som startes fra bash-prompten kalles av bash, er den nye banen gyldig for alt du starter fra bash-prompten.

Poenget er at for å legge til en ny katalog til banen, må du legge til eller legge til katalogen til miljøvariabelen $PATH i et skript inkludert i skallet, og du må eksportere miljøvariabelen $PATH.

Tilleggsinformasjon Her

I noen tid har jeg hatt med meg to funksjoner pathadd og pathrm som hjelper til med å legge til elementer i en bane uten å måtte bekymre deg for dupliseringer.

pathadd tar ett sti-argument og et valgfritt etter-argument som hvis det legges til vil bli lagt til PATH ellers vil det legge det til.

I nesten alle situasjoner, hvis du legger til en bane, vil du sannsynligvis overstyre alt som allerede er i banen, så jeg foretrekker å legge til som standard.

Pathadd() ( newelement=$(1%/) if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then if [ " $2" = "etter" ] ; deretter PATH="$PATH:$newelement" else PATH="$newelement:$PATH" fi fi ) pathrm() ( PATH="$(echo $PATH | sed -e "s; \(^\|:\)$(1%/)\(:\|\$\);\1\2;g" -e "s;^:\|:$;;g" -e "s ;::;:;g")" )

Plasser dem i et hvilket som helst skript du vil endre PATH-miljøet, og du kan nå gjøre det.

Pathadd "/foo/bar" pathadd "/baz/bat" etter eksport PATH

Du vil garantert ikke legge til en bane hvis den allerede eksisterer. Hvis du nå vil at /baz/bat skal være ved start.

Pathrm "/baz/bat" pathadd "/baz/bat" eksport PATH

Enhver sti kan nå bringes til fronten hvis den allerede er på en sti uten dobling.

Jeg kan ikke snakke for andre distribusjoner, men Ubuntu har en fil, /etc/environment, som er standard søkesti for alle brukere. Siden datamaskinen min bare brukes av meg, legger jeg de katalogene jeg vil ha i veien, så lenge det er et midlertidig tillegg som jeg legger inn i manuset.

Her er min løsning:

PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: "!x[$0]++" | sed "s/\(.*\).\(1\)/\1 /")

Fin lett liner som ikke etterlater seg:

For meg (på Mac OS X 10.9.5) fungerte det veldig bra å legge til banenavnet (f.eks. /mypathname) til /etc/paths-filen.

Før redigering returneres echo $PATH:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

Etter å ha redigert /etc/paths og restart av skallet, legges $PATH-variabelen til med /pathname . Faktisk returnerer echo $PATH:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname

Det som skjedde var at /mypathname ble lagt til $PATH .

Slik legger du til en ny bane til PATH-miljøet PATH:

Eksporter PATH=$PATH:/new-path/

For å få denne endringen til å gjelde for hvert skall du åpner, legg det til i en fil som skallet kaller opp når du kaller det. I forskjellige skall kan dette være:

  • Bash Shell: ~/.bash_profile, ~/.bashrc eller profile
  • Korn Shell: ~/.kshrc eller .profile
  • Z Shell: ~/.zshrc eller .zprofile

For eksempel

# eksport PATH=$PATH:/root/learning/bin/ # kilde ~/.bashrc # echo $PATH

Du kan se den angitte banen i utgangen ovenfor.

Alle filer i Linux har en spesifikk adresse i filsystemet som vi kan få tilgang til dem ved hjelp av en filbehandler eller konsollverktøy. Dette er et ganske enkelt emne, men mange nybegynnere har problemer med det.

I dagens korte artikkel skal vi se på hva banen til en Linux-fil er, hva den kan være, hvordan du skriver den riktig og mye mer. Hvis du hadde problemer med dette før, vil alt bli helt klart etter å ha lest artikkelen.

Filstier i Linux

Linux-filsystemet er veldig forskjellig fra Windows. Vi vil ikke vurdere strukturen, det ble gjort tidligere. Vi vil fokusere på arbeid med filer.

Den viktigste forskjellen er at filadressen ikke starter fra stasjonen, for eksempel C:\ eller D:\ som det skjer i Windows, men fra roten, rotsystemkatalogen som alle andre er koblet til. Adressen hans - /. Og her må vi snakke om adresser. Linux-filbaner bruker skråstrek "/" for å skille kataloger i adressen, og dette er forskjellig fra det du er vant til å se på Windows - \.

For eksempel, hvis i Windows fulle banen til filen på skrivebordet så ut som C:\Users\Sergiy\Desktop\, da ville filbanen i Linux ganske enkelt være /home/sergiy/desktop/. Med dette er alt enkelt og oversiktlig så langt. Men problemer oppstår videre.

I Linux-operativsystemet kan det være flere typer filstier. La oss se på hvilke veier det er i Linux:

  • Full, absolutt linux-bane fra filsystemroten- du har allerede sett denne banen i eksemplet ovenfor, den starter fra roten "/" og beskriver hele banen til filen;
  • Linux relativ bane- Dette er banen til filen i forhold til gjeldende mappe; slike stier forårsaker ofte forvirring.
  • Bane i forhold til gjeldende brukers hjemmemappe.- bane i filsystemet, men ikke fra roten, men fra gjeldende brukers mappe.

La oss nå se nærmere på hvordan disse banene ser ut i Linux, og også se på noen få eksempler for å gjøre det helt klart. For demonstrasjonen vil vi bruke ls-verktøyet, som er laget for å vise innholdet i kataloger.

For eksempel har vi en katalog som denne i hjemmemappen vår med fire filer i den:

Slik vil hele Linux-banen til en av filene se ut:

ls /home/sergiy/tmp/fil1

Dette er allerede en relativ Linux-bane, som starter fra hjemmemappen, den er betegnet ~/. Merk, ikke ~, nemlig ~/. Deretter kan du spesifisere undermapper, i vårt tilfelle tmp:

Vel, eller filbanen i Linux, i forhold til gjeldende mappe:

Den første lenken peker til gjeldende mappe (.), den andre (..) peker til en høyere mappe. Dette åpner for enda større muligheter for katalognavigering. For å referere til en fil i gjeldende mappe kan du for eksempel bruke følgende konstruksjon:

Dette er til ingen nytte når du ser på innholdet i en fil. Men det er veldig viktig når du kjører programmet. Fordi programmet vil først søkes i PATH-miljøet, og først deretter i denne mappen. Derfor, hvis du trenger å kjøre et program som ligger i den gjeldende mappen og det kalles nøyaktig det samme som det i /bin-katalogen, så uten en eksplisitt kobling må du lete etter filen i gjeldende mappe, ingenting vil fungere.

Slike konstruksjoner kan forekomme ganske ofte ved kompilering av programmer. Du kan bruke alle disse symbolene og linux-filbanene ikke bare i terminalen, men også i alle filbehandler, noe som kan være veldig praktisk.

Men Linux-terminal gir enda større muligheter. Du kan bruke enkle jokertegn direkte i fil- eller katalogadresser. For eksempel kan du liste alle filer som begynner med f:

Eller du kan til og med søke ikke bare i tmp-mappen, men i hvilken som helst undermappe til hjemmemappen din:

Og alt dette vil fungere, kanskje det er ikke alltid nødvendig og praktisk. Men i visse situasjoner kan det hjelpe mye. Disse funksjonene er implementert på Bash-skallnivå, slik at du kan bruke dem i en hvilken som helst kommando. Skallet ser på hvor mange filer som ble funnet og kaller en kommando for hver av dem.

konklusjoner

Det er alt. Nå vet du alt du trenger for ikke bare å skrive veien til riktig linux-fil, men utfører også mer komplekse handlinger, som å søke etter filer eller navigere gjennom kataloger ved å bruke cd-kommandoen. Hvis du har spørsmål, spør i kommentarene!

Relaterte innlegg:


Jeg lurer på hvor den nye banen skal legges til PATH miljøvariabelen. Jeg vet at dette kan oppnås ved å redigere .bashrc (for eksempel), men det er ikke klart hvordan du gjør dette.

Dermed:

Eksporter PATH=~/opt/bin:$PATH

Eksporter PATH=$PATH:~/opt/bin

11 svar

Enkelt materiale

PATH=$PATH:~/opt/bin PATH=~/opt/bin:$PATH

avhengig av om du vil legge til ~/opt/bin-koden til slutten (for å søke i alle andre kataloger hvis det er et program med samme navn i flere kataloger) eller til begynnelsen (for å søke før alle andre kataloger).

Du kan legge til flere oppføringer samtidig. PATH=$PATH:~/opt/bin:~/opt/node/bin eller endringer i bestillingen er helt greit.

Du trenger ikke eksportere hvis variabelen allerede er i miljøet: enhver endring i variabelens verdi gjenspeiles i miljøet.¹ PATH er stort sett alltid i miljøet; alle unix-systemer installerer det veldig tidlig (vanligvis i den aller første prosessen, faktisk).

Hvis PATHen din er opprettet av mange forskjellige komponenter, kan du ende opp med dupliserte oppføringer. Se Hvordan legge til en bane til hjemmekatalogen din som vil bli oppdaget av Unix, hvilken kommando? og Fjern dupliserte $PATH-oppføringer ved å bruke awk-kommandoen for å unngå duplikater eller fjerne dem.

Hvor du skal sette

Merk at ~/.bash_rc ikke kan leses av noe program, og ~/.bashrc er konfigurasjonsfilen for interaktive bash-forekomster. Du bør ikke definere miljøvariabler i ~/.bashrc. Det riktige stedet for å definere miljøvariabler som PATH er ~/.profile (eller ~/.bash_profile hvis du ikke liker andre skjell enn bash). Se Hva er forskjellen mellom dem og hvilken bør jeg bruke?

Merknader om ikke-bash skjell

I bash, ksh og zsh er eksport en spesiell syntaks, og både PATH=~/opt/bin:$PATH og eksport PATH=~/opt/bin:$PATH gjør det riktige til og med. På andre Bourne/POSIX-skall, for eksempel bindestrek (som er /bin/sh på mange systemer), analyseres eksport som en vanlig kommando, noe som innebærer to forskjeller:

  • ~ blir bare analysert i begynnelsen av et ord, bortsett fra i oppgaver (se Hvordan legger jeg til en hjemmekatalogbane som vil bli oppdaget av Unix som krever kommandoen? ;
  • $PATH ekstern doble anførselstegn bryter hvis PATH inneholder mellomrom eller \[*? .

Så, i skjell som bindestrek, eksport PATH=~/opt/bin:$PATH setter PATH til den bokstavelige strengen ~/opt/bin/: etterfulgt av PATH-verdien opp til første plass. PATH=~/opt/bin:$PATH (enkel oppgave) krever ikke anførselstegn og gjør alt riktig. Hvis du vil bruke eksport i et bærbart skript, må du skrive eksport PATH="$HOME/opt/bin:$PATH" eller PATH=~/opt/bin:$PATH eksportPATH (eller PATH=$HOME/opt /bin: $PATH eksport PATH for portabilitet selv til Bourne-skallet, som ikke aksepterer eksport var=verdi og ikke gjorde tilde-utvidelse).

¹ Dette var ikke sant i Bourne-skjellene (som i det faktiske Bourne-skallet, ikke moderne skjell i POSIX-stil), men du vil neppe møte skjell som er så gamle i disse dager. Sub>

Uansett fungerer det, men de gjør ikke det samme: PATH-elementer sjekkes fra venstre til høyre. I det første eksemplet vil kjørbare filer i ~/opt/bin ha forrang over de som er installert i for eksempel /usr/bin , som kanskje ikke er det du ønsker.

Spesielt er det farlig fra et sikkerhetsperspektiv å legge til stier foran, fordi hvis noen kan få skrivetilgang til din ~/opt/bin , kan de sette en annen ls for eksempel, som du sannsynligvis vil bruke i stedet /bin/ls uten å merke det. Tenk deg nå det samme for ssh eller nettleseren din eller valg ... (Samme ting tre ganger på banen din.)

Jeg er forvirret angående spørsmål 2 (siden det ble fjernet fra spørsmålet fordi det var relatert til ikke relatert problem):

Hva er en effektiv måte å legge til flere baner til forskjellige linjer? Til å begynne med tenkte jeg at dette kunne gjøre susen:

Eksport PATH=$PATH:~/opt/bin eksport PATH=$PATH:~/opt/node/bin

Men det er ikke fordi den andre oppgaven ikke bare legger til ~/opt/node/bin, men også den tidligere tildelte PATH .

Dette er en mulig løsning:

Eksporter PATH=$PATH:~/opt/bin:~/opt/node/bin

Men for lesbarheten vil jeg heller ha en destinasjon per sti.

Hvis du sier

PATH=~/opt/bin

Dette alle, som vil være i din BEI. PATH er bare en miljøvariabel, og hvis du vil legge til PATH, må du bygge om variabelen med akkurat det innholdet du ønsker. Det vil si at det du gir som eksempel i spørsmål 2 er akkurat det du ønsker å gjøre, med mindre jeg har misset helt poenget med spørsmålet.

Jeg bruker begge skjemaene i koden min. Jeg har en generell profil som jeg installerer på hver maskin jeg jobber på som ser slik ut, for å være vert for potensielt manglende kataloger:

Eksporter PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11 # legg til valgfrie elementer i banen for bindir i $HOME/local/bin $HOME/bin; gjøre hvis [ -d $bindir ]; deretter PATH=$PATH:$(bindir) fi ferdig

Linux definerer den kjørbare søkebanen med miljøvariabelen $PATH. For å legge til /data/myscripts-katalogen i begynnelsen av miljøvariabelen $PATH, bruk følgende:

PATH=/data/myscripts:$PATH

For å legge til denne katalogen på slutten av banen, bruk følgende kommando:

PATH=$PATH:/data/myscripts

Men de forrige er ikke nok fordi når du setter en miljøvariabel inne i et skript, trer denne endringen bare i kraft inne i skriptet. Denne begrensningen er begrenset på to måter:

  • Hvis du eksporterer en miljøvariabel i et skript, er den effektiv i alle programmer som kalles av skriptet. Merk at dette ikke er effektivt i programmet som kalte skriptet.
  • Hvis programmet som kaller skriptet gjør det ved å inkludere i stedet for å ringe, vil eventuelle miljøendringer i skriptet være effektive på det kallende programmet. Denne inkluderingen kan gjøres ved å bruke dot-kommandoen eller kildekommandoen.

$HOME/myscript.sh kilde $HOME/myscript.sh

Inkludering inkluderer i utgangspunktet det "anropbare" skriptet i "call"-skriptet. Dette ligner på #include i C. Så det er effektivt inne i et skript eller et kalleprogram. Men dette er selvfølgelig ikke effektivt for noen programmer eller skript som kalles opp av programmet. For å gjøre det effektivt ned til anropskjeden, må du følge miljøvariabelinnstillingen ved å bruke eksportkommandoen.

Som et eksempel inkluderer bash shell-programmet innholdet i .bash_profile-filen ved inkludering. Så legg inn følgende 2 linjer i .bash_profile:

PATH=$PATH:/data/myscripts eksport PATH

setter effektivt de 2 kodelinjene inn i et bash-program. Så i bash inkluderer $PATH-variabelen $HOME/myscript.sh, og på grunn av eksportsetningen har alle programmer kalt av bash $PATH-variabelen endret. Og siden alle programmer du starter fra bash-prompten kalles av bash, gjelder den nye banen for alt du starter fra bash-prompten.

Poenget er at for å legge til en ny katalog til banen, må du legge til eller legge til katalogen til miljøvariabelen $PATH i et skript inkludert i skallet, og du må eksportere miljøvariabelen $PATH.

Jeg har hatt med meg en stund to funksjoner pathadd og pathrm som hjelper til med å legge til elementer i en bane uten å bekymre deg for dupliseringer.

pathadd tar ett sti-argument og et valgfritt etter-argument, som hvis det legges til vil bli lagt til PATH , ellers vil det legge det til.

I alle situasjoner, hvis du legger til en bane, vil du sannsynligvis overstyre alt som allerede er i banen, så jeg foretrekker å legge til som standard.

Pathadd() ( newelement=$(1%/) if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then if [ " $2" = "etter" ] ; deretter PATH="$PATH:$newelement" else PATH="$newelement:$PATH" fi fi ) pathrm() ( PATH="$(echo $PATH | sed -e "s; \(^\|:\)$(1%/)\(:\|\$\);\1\2;g" -e "s;^:\|:$;;g" -e "s ;::;:;g")" )

Plasser dem i det skriptet du vil endre PATH-miljøet, og du er nå ferdig.

Pathadd "/foo/bar" pathadd "/baz/bat" etter eksport PATH

Du vil garantert ikke legge til en bane hvis den allerede eksisterer. Hvis du vil at /baz/bat skal kjøres først.

Pathrm "/baz/bat" pathadd "/baz/bat" eksport PATH

Enhver sti kan nå flyttes til fronten hvis den allerede er på en sti uten å doble.

Skuddsikker tilleggs-/forberedelsesmetode

Det er mange hensyn involvert i å velge å legge til og legge til. Mange av dem er dekket i andre svar, så jeg skal ikke gjenta dem her.

Det viktige poenget er at selv om systemskript ikke bruker dette (jeg lurer på hvorfor) *1, er det en skuddsikker måte å legge til en bane (f.eks. $HOME/bin) til PATH miljøvariabelen

PATH="$(PATH:+$(PATH):)$HOME/bin"

å legge til (i stedet for PATH="$PATH:$HOME/bin") og

PATH="$HOME/bin$(PATH:+:$(PATH))"

å legge til (i stedet for PATH="$HOME/bin:$PATH")

Dette unngår en falsk innledende/etterfølgende kolon når $PATH i utgangspunktet er tom, noe som kan ha uønskede bivirkninger og kan være et mareritt å finne (dette svaret tar kort for seg den vanskelige saken).

$(parameter:+ord)

Hvis parameteren er null eller deaktivert, erstattes ingenting, ellers erstattes den ord ord.

Så $(PATH:+$(PATH):) utvides til: 1) ingenting hvis PATH er null eller deaktivert, 2) $(PATH): hvis PATH er satt.

Merk. Dette er for bash.

*1 Jeg fant nettopp ut at skript som devtoolset-6/enable bruker dette, $ cat /opt/rh/devtoolset-6/enable # Generelle miljøvariabler eksport PATH=/opt/rh/devtoolset-6/root/usr /bin $(PATH:+:$(PATH)) ...

Jeg kan ikke snakke for andre distribusjoner, men Ubuntu har en fil, /etc/environment, som er standard søkesti for alle brukere. Siden datamaskinen min bare brukes av meg, legger jeg de katalogene jeg vil ha i veien der, med mindre det er et midlertidig tillegg jeg legger inn i skriptet.

For meg (på Mac OS X 10.9.5) fungerte det veldig bra å legge til banenavnet (f.eks. /mypathname) til /etc/paths-filen.

Før redigering returneres echo $PATH:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

Etter å ha redigert /etc/paths og restart av skallet, legges $PATH-variabelen til med /pathname . Faktisk returnerer echo $PATH:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname

Det som skjedde var at /mypathname ble lagt til $PATH-variabelen.