Script for at ændre den aktuelle mappe (cd, pwd)

Jeg vil køre et script for blot at ændre den aktuelle arbejdsmappe:

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

Men efter at jeg har kørt det, forbliver den aktuelle pwd uændret! Hvordan kan jeg gøre det?

Svar

Det er en forventet adfærd. Scriptet køres i en subshell og kan ikke ændre den overordnede shell-arbejdsmappe. Dens virkninger går tabt, når den er færdig.

For at ændre den aktuelle shell-mappe permanent skal du bruge kommandoen source, også aliaset simpelthen som ., der kører et script i det aktuelle shell-miljø i stedet for en sub-shell.

Følgende kommandoer er identiske:

. script 

eller

source script 

Kommentarer

  • @Sony: Bemærk, at du skal bruge return for at flygte fra et script, der er hentet på denne måde, ikke exit – de er som shellfunktioner, og exit afslutter den shell, der stammer fra scriptet.
  • @CharlesStewart Faktisk er jeg ‘ jeg er ikke bekendt med sourcede scripts. Tak!
  • er source ./script det samme?
  • @amyassin: ja, det er
  • 1. . og source er ens i bash. 2. vi don ‘ behøver ikke at bruge ./ før filnavnet, hvis det ‘ er i samme bibliotek. Det er ok at kun køre dette: . script

Svar

For små opgaver som dette skal du oprette et alias som dette i stedet for at oprette script

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

Du skal føje dette til din .bashrc -fil, hvis du vil have den indstillet til hver interaktiv shell.

Nu kan du køre denne som $ cdproj.

Kommentarer

  • Du kan også få scriptet til at ekko de kommandoer, der skal udføres, og derefter bruge eval `./script` eller eval $(./script) for at udføre disse kommandoer. Dette er en almindelig tilgang til kommandoer, der har brug for at opdatere den påkaldende shell ‘ s miljø.
  • Bare vær meget forsigtig med hvad du sender, hvis du vil gå eval tilgang.

Svar

Brug exec bash i slutningen

Et bash-script fungerer på dets nuværende miljø eller på dets børns, men aldrig på dets overordnet miljø.

Dette spørgsmål bliver dog ofte stillet, fordi man vil have prompt i et bestemt bibliotek efter udførelsen af et bash-script fra en anden mappe.

Hvis dette er tilfældet, skal du blot udføre en underordnet bash-forekomst i slutningen af scriptet:

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

Dette skaber en ny subshell. Skriv Ctrl + D eller exit for at vende tilbage til den første skal, hvor scriptet oprindeligt blev startet.

Opdatering

I det mindste med nyere versioner af bash er exec på den sidste linje ikke længere påkrævet. Desuden kan scriptet fås til at arbejde med den foretrukne shell ved hjælp af miljøvariablen $SHELL. Dette giver derefter:

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

Kommentarer

  • Bedre at bare kilde scriptet, som i accepteret svar : Brug af exec betragtes typisk som den sidste udvej for en skurk .. 🙂
  • dette trick betyder ikke ‘ t arbejde i debian 9-strækning.
  • Dette er den forkerte måde at gøre dette på!
  • Da ingen har detaljeret problemerne med dette (jeg ser på dig, @Dennis): (1) Hver gang du kører dette, opretter det en ny, vedvarende bash-proces. Gør det ti eller tyve gange i en session, så får du 11 til 21 bash-processer samlet. Dette kan påvirke ydeevnen, og hvis du prøver at afslutte sessionen rent ved at skrive exit (eller Ctrl + D), bliver du nødt til at gøre det 11 til 21 gange. (2) En anden ulempe ved at bruge et eksekverbart script er, at hvis du indstiller shellindstillinger (f.eks. dotglob eller globstar) i din interaktiv shell-session, mister du dem, fordi du starter en ny shell.
  • Meget flot løsning! Jeg ‘ har omskrevet mit alias i bash_profile, så nu er det et script, der er gemt i en separat fil. Jeg bruger scriptet til at gå til en nyoprettet midlertidig mappe. Og nu er det endnu nemmere at have en midlertidig bash-session. SRP i aktion! Tak!

Svar

Mens der er svar, der udfører den nøjagtige handling, du ønsker, en mere standard metode til sådan formålet er at oprette symbolsk link:

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

Så kunne du cd til biblioteket ved hjælp af navnet proj:

cd proj 

Denne metode er mere fleksibel, fordi du kunne få adgang til filer ved hjælp af det korte navn uden cd:

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

Svar

Afhænger af hvad du “vil en anden løsning være at oprette en funktion i stedet for et script.

Eksempel:

Opret en funktion i en fil, lad os sige /home/aidin/my-cd-script:

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

Medtag det derefter i din bashrc eller zshrc fil:

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

Nu kan du bruge den som en kommando:

$ my-cd 

Svar

Hvis du skifter mellem mapper langt væk i filsystemet. Jeg vil anbefale autojump .

Svar

For mig var den mest bekvemme og fleksible tilgang en blanding af et alias og et script:

opret script med vilkårlig logik

Her opretter jeg et script, der skifter til et bibliotek og aktiverer det passende python-miljø. Scriptsplaceringen er eksempler på /path/to/workon_myproj.sh.

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

Opret alias, der kilder scriptet

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

Tilføj aliasdefinitionen i din passende shell-startfil f.eks. .profile, .bashrc eller .zshrc.

resultat

Du kan nu simpelthen udføre workon_myproj i en shell, der kilder indholdet af dit script i den ønskede mappe.

udvidelse

Du kan eventuelt forbedre dit script for at tage et argument, så det fungerer med flere projekter i en bestemt arbejdsmappe eller kombinere det med en git pull for at få de seneste ændringer med det samme og så på … alt kedelplade ting, du gør, når du fortsætter med at arbejde på et specifikt projekt.

Svar

Hvorfor ikke bruge ” udføre “det sømmer sig at gøre præcis, hvad jeg ønsker.

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

Kommentarer

  • Pas på ting, der synes at være, hvad du vil have. (En kæmpe træhest! Lige hvad jeg ville have!) Hver gang du kører dette, skaber det en ny, vedvarende bash-proces. Gør det ti eller tyve gange i en session, så får du 11 til 21 bash-processer stablet. Dette kan påvirke ydeevnen, og hvis du prøver at afslutte sessionen rent ved at skrive exit (eller Ctrl + D), bliver du nødt til at gøre det 11 til 21 gange.
  • Jeg kunne bestemt se, hvor det ville være et problem. For mig selvom jeg ‘ bruger det en gang, laver det arbejde, jeg har brug for, og derefter afslutter. Hvis ‘ er den eneste ulempe, er jeg kan leve med det. På den anden side, hvis der er en bedre løsning, er jeg ‘ villig til at se på det.
  • Aidins svar på dette spørgsmål ved hjælp af en shell-funktion og Sachin Divekars svar ved hjælp af et alias er (IMO) bedre løsninger end at bruge et script . P.S. En anden ulempe ved at bruge et script er, at hvis du angiver nogle shell-indstillinger (f.eks. dotglob eller globstar), mister du dem, fordi du starter en ny skal. … (fortsat)
  • (fortsat) … P.P.S. Jeg har lige bemærket, at du grundlæggende gentager Serge Stroobandts svar og siger Hvorfor ikke gøre det? På Stack Exchange vi forventer, at svarene giver nye ideer og / eller information og ikke kun diskuterer andre svar.

Svar

Dette kombinerer svaret af Serge med et ikke-relateret svar af David . Det ændrer biblioteket, og i stedet for at tvinge en bash-shell starter den brugerens standardskal . Det kræver dog både getent og /etc/passwd for at opdage standardskallen.

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

Dette har naturligvis stadig den samme mangel på at skabe en indlejret shell.

Svar

Du kan gøre det ved hjælp af en funktion eller ved hjælp af & & Eksemplerne nedenfor viser Zabbix og opretter en fil med en linje indeni.

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 

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *