Skript for å endre nåværende katalog (cd, pwd)

Jeg vil kjøre et skript for å bare endre gjeldende arbeidskatalog:

#!/bin/bash cd web/www/project 

Men etter at jeg har kjørt den, forblir den nåværende pwd uendret! Hvordan kan jeg gjøre det?

Svar

Det er en forventet oppførsel. Skriptet kjøres i en subshell, og kan ikke endre den overordnede skallets arbeidskatalog. Effektene går tapt når den er ferdig.

For å endre den gjeldende skallkatalogen permanent, bør du bruke source -kommandoen, også alias bare som ., som kjører et skript i det gjeldende skallmiljøet i stedet for et underskall.

Følgende kommandoer er identiske:

. script 

eller

source script 

Kommentarer

  • @Sony: Merk at du bør bruke return for å flykte fra et skript som er hentet på denne måten, ikke exit – de er som skallfunksjoner, og exit kommer ut av skallet som hentet skriptet.
  • @CharlesStewart Faktisk, jeg ‘ Jeg er ikke kjent med hentede skript. Takk!
  • er source ./script det samme?
  • @amyassin: ja, det er
  • 1. . og source er like i bash. 2. vi don ‘ trenger ikke å bruke ./ før filnavnet hvis det ‘ er i samme katalog. Det er ok å bare kjøre dette: . script

Svar

For små oppgaver som dette, i stedet for å lage skript, opprett et alias som dette,

$ alias cdproj="cd /dir/web/www/proj" 

Du bør legge til dette i .bashrc -fil, hvis du vil at den skal angis for hvert interaktive skall.

Nå kan du kjøre denne som $ cdproj.

Kommentarer

  • Du kan også få skriptet til å ekko kommandoene som skal utføres, og deretter bruke eval `./script` eller eval $(./script) for å utføre disse kommandoene. Dette er en vanlig tilnærming for kommandoer som trenger å oppdatere det påkallende skallet ‘ s miljø.
  • Bare vær veldig forsiktig med hva du sender ut hvis du skal gå eval tilnærmingen.

Svar

Bruk exec bash på slutten

Et bash-skript fungerer på det nåværende miljøet eller på barna sine, men aldri på dets foreldremiljø.

Dette spørsmålet blir imidlertid ofte stilt fordi man vil være igjen spør i en bestemt katalog etter utførelsen av et bash-skript fra en annen katalog.

Hvis dette er tilfelle, kan du bare utføre en underordnet bash-forekomst på slutten av skriptet:

#!/usr/bin/env bash cd desired/directory exec bash 

Dette skaper en ny subshell. Skriv Ctrl + D eller exit for å gå tilbake til det første skallet der skriptet ble startet.

Oppdater

I det minste med nyere versjoner av bash er exec på siste linje ikke lenger nødvendig. Videre kan skriptet få det til å fungere med hvilket som helst foretrukket skall ved å bruke miljøvariabelen $SHELL. Dette gir deretter:

#!/usr/bin/env bash cd desired/directory $SHELL 

Kommentarer

  • Bedre å bare kildeskriptet, som i akseptert svar : å bruke exec regnes vanligvis som siste utvei for en skurk .. 🙂
  • dette trikset betyr ikke ‘ t arbeid i debian 9 stretch.
  • Dette er feil måte å gå på!
  • Siden ingen har detaljert problemene med dette (jeg ser på deg, @Dennis): (1) Hver gang du kjører dette, skaper det en ny, vedvarende bash-prosess. Gjør det ti eller tjue ganger i løpet av en økt, så får du 11 til 21 bash-prosesser som er samlet. Dette kan påvirke ytelsen, og hvis du prøver å avslutte økten på en ren måte ved å skrive exit (eller Ctrl + D), må du gjøre det 11 til 21 ganger. (2) En annen ulempe ved å bruke et kjørbart skript er at hvis du angir noen skallalternativer (f.eks. dotglob eller globstar) interaktiv skalløkt, vil du miste dem, fordi du starter et nytt skall.
  • Veldig fin løsning! Jeg ‘ har skrevet om aliaset mitt i bash_profile, så nå er det et skript som er lagret i en egen fil. Jeg bruker skriptet til å gå til en nylig opprettet midlertidig mappe. Og nå er det enda lettere å ha en midlertidig bash-økt. SRP i aksjon! Takk!

Svar

Selv om det er svar som gjør den nøyaktige handlingen du ønsker, er en mer standard metode for slike Hensikten er å opprette symbolsk lenke:

ln -s ~/web/www/project proj #use full path to dir! 

Deretter kan du cd til katalogen ved hjelp av navnet proj:

cd proj 

Denne metoden er mer fleksibel fordi du har tilgang til filer ved å bruke det korte navnet uten cd:

ls proj/ #note the endslash! vim proj/file.x 

Svar

Avhenger av hva du «skal vi gjøre, en annen løsning kan være å opprette en funksjon i stedet for et skript.

Eksempel:

Opprett en funksjon i en fil, la oss si /home/aidin/my-cd-script:

function my-cd() { cd /to/my/path } 

Ta det med i bashrc eller zshrc fil:

# Somewhere in rc file source /home/aidin/my-cd-script 

Nå kan du bruke den som en kommando:

$ my-cd 

Svar

Hvis du bytter mellom kataloger langt borte i filsystemet. Jeg vil anbefale autojump .

Svar

For meg var den mest praktiske og fleksible tilnærmingen en blanding av et alias og et skript:

lag skript med vilkårlig logikk

Her oppretter jeg et skript som endres til en katalog og aktiverer riktig python-miljø. Skriptplasseringen er eksempler på /path/to/workon_myproj.sh.

#!/usr/bin/env bash cd $HOME/workspace/myproj source .venv/bin/activate 

oppretter alias som kilder skriptet

alias workon_myproj="source /path/to/workon_myproj.sh" 

Legg til aliasdefinisjonen i riktig shell-startfil, f.eks. .profile, .bashrc eller .zshrc.

utfall

Du kan nå bare utføre workon_myproj i et skall som kilder innholdet i skriptet i ønsket katalog.

utvidbarhet

Du kan eventuelt forbedre skriptet ditt for å ta et argument slik at det fungerer med flere prosjekter i en bestemt arbeidskatalog, eller kombinere det med en git pull for å få de siste endringene umiddelbart og så på … alt kjeleplaten ting du gjør når du fortsetter å jobbe med et bestemt prosjekt.

Svar

Hvorfor ikke bruke » exec «det sømmer å gjøre akkurat det jeg ønsker.

#!/bin/bash cd someplace exec bash ~/someplace 

Kommentarer

  • Vokt dere for ting som synes å være det du vil ha. (En gigantisk trehest! Akkurat det jeg ville!) Hver gang du kjører dette, skaper det en ny, vedvarende bash-prosess. Gjør det ti eller tjue ganger i løpet av en økt, så får du 11 til 21 bash-prosesser. Dette kan påvirke ytelsen, og hvis du prøver å avslutte økten på en ren måte ved å skrive exit (eller Ctrl + D), må du gjøre det 11 til 21 ganger.
  • Jeg kunne definitivt se hvor det ville være et problem. For meg selv om jeg ‘ bruker det en gang, gjør jeg det arbeidet jeg trenger og deretter avslutter. Hvis det ‘ er den eneste ulempen kan leve med det. På den annen side hvis det er en bedre løsning, er jeg ‘ villig til å se på den.
  • Aidins svar på dette spørsmålet , ved hjelp av en skallfunksjon, og Sachin Divekars svar , ved hjelp av et alias, er (IMO) bedre løsninger enn å bruke et skript . P.S. En annen ulempe ved å bruke et skript er at hvis du angir noen shell-alternativer (f.eks. dotglob eller globstar), vil du miste dem, fordi du starter et nytt skall. … (forts.)
  • (forts.) … P.P.S. Jeg la merke til at du i utgangspunktet gjentar Serge Stroobandts svar og sa Hvorfor ikke gjøre dette? På Stack Exchange vi forventer at svarene gir nye ideer og / eller informasjon, og ikke bare diskuterer andre svar.

Svar

Dette kombinerer svaret av Serge med et urelatert svar av David . Det endrer katalogen, og i stedet for å tvinge et bash-skall, starter brukerens standardskall . Det krever imidlertid både getent og /etc/passwd for å oppdage standardskallet.

 #!/usr/bin/env bash cd desired/directory USER_SHELL=$(getent passwd <USER> | cut -d : -f 7) $USER_SHELL  

Dette har selvfølgelig fortsatt den samme mangelen på å lage et nestet skall.

Svar

Du kan gjøre det ved hjelp av en funksjon eller ved å bruke & & Eksemplene nedenfor installerer Zabbix og oppretter en fil med en linje inni.

Eks:

#!/bin/bash # Create Function: installZabbix(){ cd /usr/src/zabbix-4.2.4; ./configure --enable-agent; make install; cd /usr/src/; >file; echo "Hi, this is a file." >>file; } # Call the function: installZabbix 

eller:

#!/bin/bash cd /usr/src/zabbix-4.2.4 && ./configure --enable-agent && make install && cd /usr/src && >file && echo "Hi, this is a file." >>file 

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *