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
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`
ellereval $(./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
ellerglobstar
) 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
ellerglobstar
), 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
return
for at flygte fra et script, der er hentet på denne måde, ikkeexit
– de er som shellfunktioner, ogexit
afslutter den shell, der stammer fra scriptet.source ./script
det samme?.
ogsource
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