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
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`
ellereval $(./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
ellerglobstar
) 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
ellerglobstar
), 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
return
for å flykte fra et skript som er hentet på denne måten, ikkeexit
– de er som skallfunksjoner, ogexit
kommer ut av skallet som hentet skriptet.source ./script
det samme?.
ogsource
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