Skript för att ändra aktuell katalog (cd, pwd)

Jag vill köra ett skript för att helt enkelt ändra den aktuella arbetskatalogen:

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

Men efter att jag kör det är den nuvarande pwd oförändrad! Hur kan jag göra det?

Svar

Det är ett förväntat beteende. Skriptet körs i en subshell och kan inte ändra den överordnade skalets arbetskatalog. Dess effekter går förlorade när den är klar.

För att ändra den aktuella skalkatalogen permanent bör du använda kommandot source, även alias helt enkelt som ., som kör ett skript i den aktuella skalmiljön istället för ett underskal.

Följande kommandon är identiska:

. script 

eller

source script 

Kommentarer

  • @Sony: Observera att du ska använda return för att fly från ett skript som härrör från detta sätt, inte exit – de är som skalfunktioner och exit kommer att lämna skalet som skriptet har skaffat.
  • @CharlesStewart Jag ’ Jag känner faktiskt inte till skript. Tack!
  • är source ./script samma?
  • @amyassin: ja, det är
  • 1. . och source är lika i bash. 2. vi ’ behöver inte använda ./ före filnamn om det ’ är i samma katalog. Det är ok att bara köra detta: . script

Svar

För små uppgifter som detta, istället för att skapa skript, skapa ett alias så här,

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

Du bör lägga till detta i din .bashrc -fil, om du vill att den ska ställas in för varje interaktivt skal.

Nu kan du köra den som $ cdproj.

Kommentarer

  • Du kan också låta manuset eka kommandona som ska köras och sedan använda eval `./script` eller eval $(./script) för att utföra dessa kommandon. Detta är ett vanligt tillvägagångssätt för kommandon som behöver uppdatera det anropande skalet ’ s miljö.
  • Var bara mycket försiktig med vad du matar ut om du ska gå eval tillvägagångssätt.

Svar

Använd exec bash i slutet

Ett bash-skript fungerar på sin nuvarande miljö eller på dess barn, men aldrig på dess föräldermiljö.

Denna fråga ställs dock ofta eftersom man vill lämnas vid bash fråga i en viss katalog efter körningen av ett bash-skript från en annan katalog.

Om detta är fallet, kör du bara en underordnad bash-instans i slutet av skriptet:

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

Detta skapar en ny subshell. Skriv Ctrl + D eller exit för att återgå till det första skalet där skriptet ursprungligen startades.

Uppdatering

Åtminstone med nyare versioner av bash är exec på den sista raden inte längre nödvändig. Dessutom kan skriptet fungera med vilket föredraget skal som helst genom att använda miljövariabeln $SHELL. Detta ger sedan:

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

Kommentarer

  • Bättre att bara källa skriptet, som i accepterat svar : att använda exec anses vanligtvis vara den sista utväg för en skurk … 🙂
  • det här tricket ’ t arbeta i debian 9 stretch.
  • Det här är fel sätt att göra detta!
  • Eftersom ingen har beskrivit problemen med detta (jag tittar på dig, @Dennis): (1) Varje gång du kör detta skapar det en ny, ihållande bash-process. Gör det tio eller tjugo gånger i en session, så får du 11 till 21 bash-processer. Detta kan påverka prestandan och om du försöker avsluta sessionen rent genom att skriva exit (eller Ctrl + D) måste du göra det 11 till 21 gånger. (2) En annan nackdel med att använda ett körbart skript är att om du anger några skalalternativ (t.ex. dotglob eller globstar) interaktiv skalsession kommer du att förlora dem eftersom du startar ett nytt skal.
  • Mycket trevlig lösning! Jag ’ har skrivit om mitt alias i bash_profile så nu är det ett skript som lagras i en separat fil. Jag använder skriptet för att gå till en nyskapad tillfällig mapp. Och nu är det ännu lättare att ha en tillfällig bash-session. SRP i aktion! Tack!

Svar

Även om det finns svar som gör den exakta åtgärd som du vill, en mer standardmetod för sådana syftet är att skapa symbolisk länk:

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

Då kan du cd till katalogen med namnet proj:

cd proj 

Denna metod är mer flexibel eftersom du kan komma åt filer med det korta namnet utan cd:

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

Svar

Beror på vad du ”kommer att göra, en annan lösning kan vara att skapa en funktion istället för ett skript.

Exempel:

Skapa en funktion i en fil, låt oss säga /home/aidin/my-cd-script:

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

Inkludera det sedan i din bashrc eller zshrc fil:

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

Nu kan du använda den som ett kommando:

$ my-cd 

Svara

Om du byter mellan kataloger långt borta i filsystemet. Jag kommer att rekommendera autojump .

Svar

För mig var det mest bekväma och flexibla tillvägagångssättet en blandning av ett alias och ett skript:

skapa skript med godtycklig logik

Här skapar jag ett skript som ändras till en katalog och aktiverar lämplig pythonmiljö. Skriptplatsen är exempel på /path/to/workon_myproj.sh.

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

skapa alias som källskript

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

Lägg till aliasdefinitionen i din lämpliga shell-startfil t.ex. .profile, .bashrc eller .zshrc.

utfall

Du kan nu bara köra workon_myproj i ett skal som kommer att källa till innehållet i ditt skript i önskad katalog.

töjbarhet

Du kan eventuellt förbättra ditt skript för att ta ett argument så att det fungerar med flera projekt i en viss arbetskatalog eller kombinera det med en git pull för att få de senaste ändringarna omedelbart och så på … allt pannplattans grejer du gör när du fortsätter att arbeta med ett visst projekt.

Svar

Varför inte använda ” exec ”det sömmar att göra exakt vad jag önskar.

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

Kommentarer

  • Se upp för saker som verkar vara vad du vill ha. (En jätte trähäst! Precis vad jag ville!) Varje gång du kör detta skapar det en ny, ihållande bash-process. Gör det tio eller tjugo gånger under en session, så har du 11 till 21 bash-processer staplade. Detta kan påverka prestandan och om du försöker avsluta sessionen rent genom att skriva exit (eller Ctrl + D) måste du göra det 11 till 21 gånger.
  • Jag kunde definitivt se var det skulle vara ett problem. För mig ändå ’ jag använder det en gång, gör det arbete jag behöver och sedan avslutar. Om det är ’ är jag kan leva med det. Å andra sidan om det finns en bättre lösning är jag ’ villig att titta på den.
  • Aidins svar på den här frågan , med en skalfunktion, och Sachin Divekars svar , med hjälp av ett alias, är (IMO) bättre lösningar än att använda ett skript . P.S. En annan nackdel med att använda ett skript är att om du anger några skalalternativ (t.ex. dotglob eller globstar) kommer du att förlora dem, för att du startar ett nytt skal. … (Fortsätt)
  • (Fortsätt) … P.P.S. Jag märkte bara att du i grund och botten upprepar Serge Stroobandts svar och säger Varför inte göra det här? Vid Stack Exchange vi förväntar oss att svar ger nya idéer och / eller information, och inte bara diskuterar andra svar.

Svar

Detta kombinerar svaret av Serge med ett orelaterat svar av David . Det ändrar katalogen och istället för att tvinga ett bash-skal startar det användarens standardskal . Det kräver dock både getent och /etc/passwd för att upptäcka standardskalet.

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

Naturligtvis har detta fortfarande samma brist att skapa ett kapslat skal.

Svar

Du kan göra det med en funktion eller med hjälp av & & Exemplen nedan installerar Zabbix och skapar en fil med en rad inuti.

Ex:

#!/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 

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *