Ik wil een script uitvoeren om eenvoudig de huidige werkdirectory te wijzigen:
#!/bin/bash cd web/www/project
Maar nadat ik het heb uitgevoerd, blijft de huidige pwd ongewijzigd! Hoe kan ik dat doen?
Antwoord
Het is een verwacht gedrag. Het script wordt in een subshell uitgevoerd en kan de werkdirectory van de bovenliggende shell niet wijzigen. De effecten gaan verloren als het klaar is.
Om de huidige shell-directory permanent te wijzigen, moet je het source
commando gebruiken, ook alias simpelweg als .
, die een script in de huidige shell-omgeving uitvoert in plaats van een subshell.
De volgende commandos zijn identiek:
. script
of
source script
Reacties
Antwoord
Maak voor kleine taken zoals deze, in plaats van een script te maken, een alias zoals deze,
$ alias cdproj="cd /dir/web/www/proj"
Voeg dit toe aan uw .bashrc
bestand, als je het voor elke interactieve shell wilt instellen.
Nu kun je dit uitvoeren als $ cdproj
.
Opmerkingen
- U kunt het script ook de uit te voeren opdrachten laten herhalen, en vervolgens
eval `./script`
ofeval $(./script)
om die opdrachten uit te voeren. Dit is een gebruikelijke benadering voor commandos die de aanroepende shell ‘ s omgeving moeten updaten. - Wees gewoon heel voorzichtig met wat je uitvoert als je gaat de
eval
benadering.
Antwoord
Gebruik exec bash
aan het einde
Een bash-script werkt op zijn huidige omgeving of op die van zijn kinderen, maar nooit op zijn bovenliggende omgeving.
Deze vraag wordt echter vaak gesteld omdat men bij de bash wil laten staan prompt in een bepaalde map na de uitvoering van een bash-script uit een andere map.
Als dit het geval is, voer dan gewoon een kind bash-instantie uit aan het einde van het script:
#!/usr/bin/env bash cd desired/directory exec bash
Dit creëert een nieuwe subshell. Typ Ctrl + D of exit
om terug te keren naar de eerste shell waar het script oorspronkelijk was gestart.
Update
In ieder geval met nieuwere versies van bash
, is de exec
op de laatste regel niet langer nodig. Bovendien kan het script worden gemaakt om te werken met elke gewenste shell door de omgevingsvariabele $SHELL
te gebruiken. Dit geeft dan:
#!/usr/bin/env bash cd desired/directory $SHELL
Reacties
- Het is beter om alleen het script te vinden, zoals in een geaccepteerd antwoord :
exec
gebruiken wordt doorgaans beschouwd als het laatste redmiddel van een schurk .. 🙂 - deze truc doet ‘ niet werk in debian 9 stretch.
- Dit is de verkeerde manier om dit aan te pakken!
- Aangezien niemand de problemen hiermee heeft beschreven (ik kijk naar jou, @Dennis): (1) Elke keer dat u dit uitvoert, wordt er een nieuw, persistent bash-proces gecreëerd. Doe het tien of twintig keer in een sessie en je hebt 11 tot 21 bash-processen opgestapeld. Dit kan de prestaties beïnvloeden, en als u de sessie netjes probeert te beëindigen door
exit
(of Ctrl + D) te typen, moet u dat 11 tot 21 keer doen. (2) Een ander nadeel van het gebruik van een uitvoerbaar script is dat, als u shell-opties instelt (bijv.dotglob
ofglobstar
) in uw interactieve shell-sessie, je raakt ze kwijt, omdat je een nieuwe shell begint. - Zeer mooie oplossing! Ik ‘ heb mijn alias herschreven in bash_profile, dus nu is het een script dat is opgeslagen in een apart bestand. Ik gebruik het script om naar een nieuw aangemaakte tijdelijke map te gaan. En nu is het nog gemakkelijker om een tijdelijke bash-sessie te houden. SRP in actie! Bedankt!
Antwoord
Hoewel er antwoorden zijn die precies de actie uitvoeren die u wilt, is een meer standaardmethode voor dergelijke doel is om een symbolische link te maken:
ln -s ~/web/www/project proj #use full path to dir!
Dan kun je cd
naar de directory met de naam proj
:
cd proj
Deze methode is flexibeler omdat u bestanden kunt openen met de korte naam zonder cd
:
ls proj/ #note the endslash! vim proj/file.x
Antwoord
Hangt af van wat u “gaan doen, kan een andere oplossing zijn om een functie te maken in plaats van een script.
Voorbeeld:
Maak een functie in een bestand, laten we zeggen /home/aidin/my-cd-script
:
function my-cd() { cd /to/my/path }
Voeg het vervolgens toe aan uw bashrc
of zshrc
bestand:
# Somewhere in rc file source /home/aidin/my-cd-script
Nu kun je het gebruiken als een commando:
$ my-cd
Antwoord
Als u wisselt tussen mappen ver weg in het bestandssysteem. Ik zal autojump aanbevelen.
Answer
Voor mij was de handigste en meest flexibele benadering een combinatie van een alias en een script:
maak script met willekeurige logica
Hier maak ik een script dat naar een map verandert en de juiste python-omgeving activeert. De locatie van het script is voorbeeldig in /path/to/workon_myproj.sh
.
#!/usr/bin/env bash cd $HOME/workspace/myproj source .venv/bin/activate
maak alias aan die script bron
alias workon_myproj="source /path/to/workon_myproj.sh"
Voeg de aliasdefinitie toe aan uw geschikte shell-startbestand, bijv. .profile
, .bashrc
of .zshrc
.
resultaat
U kunt nu eenvoudig workon_myproj
uitvoeren in een shell die de inhoud van uw script in de gewenste directory plaatst.
uitbreidbaarheid
Je zou je script kunnen verbeteren om een argument te accepteren zodat het werkt met meerdere projecten in een specifieke werkdirectory, of het combineren met een git pull
om de laatste wijzigingen onmiddellijk te krijgen en zo op … alles wat je doet als je aan een specifiek project blijft werken.
Answer
Waarom zou je “niet gebruiken” exec “het lijkt erop om precies te doen wat ik wil.
#!/bin/bash cd someplace exec bash ~/someplace
Reacties
- Pas op voor dingen die lijken te zijn wat u wilt. (Een gigantisch houten paard! Precies wat ik wilde!) Elke keer dat je dit uitvoert, creëert het een nieuw, aanhoudend bash-proces. Doe het tien of twintig keer in een sessie, en je hebt 11 tot 21 bash-processen gestapeld. Dit kan de prestaties beïnvloeden, en als u de sessie netjes probeert te beëindigen door
exit
(of Ctrl + D) te typen, moet u dat 11 tot 21 keer doen. - Ik kon zeker zien waar dat een probleem zou zijn. Maar voor mij ‘ gebruik ik het een keer, doe ik het werk dat ik nodig heb en stop ik dan. Als dat ‘ het enige nadeel is dat ik kan ermee leven. Aan de andere kant, als er een betere oplossing is, ben ik ‘ bereid ernaar te kijken.
- Aidins antwoord op deze vraag , met behulp van een shell-functie, en Sachin Divekars antwoord , met behulp van een alias, zijn (IMO) betere oplossingen dan het gebruik van een script . P.S. Een ander nadeel van het gebruik van een script is dat als je shell-opties instelt (bijv.
dotglob
ofglobstar
), je ze kwijtraakt, omdat je een nieuwe shell begint. … (vervolg) - (vervolg) … P.P.S. Ik heb net gemerkt dat je in feite het antwoord van Serge Stroobandt herhaalt en zegt Waarom doe je dit niet? Op Stack Exchange we verwachten dat antwoorden nieuwe ideeën en / of informatie opleveren, en niet alleen andere antwoorden bespreken.
Answer
Dit combineert het antwoord van Serge met een niet-gerelateerd antwoord van David . Het verandert de directory, en in plaats van een bash-shell te forceren, start het de standaardshell van de gebruiker . Het vereist echter beide getent
en /etc/passwd
om de standaard shell te detecteren.
#!/usr/bin/env bash cd desired/directory USER_SHELL=$(getent passwd <USER> | cut -d : -f 7) $USER_SHELL
Natuurlijk heeft dit nog steeds dezelfde tekortkoming als het maken van een geneste shell.
Antwoord
U kunt dat doen met een functie of met & & De onderstaande voorbeelden installeert Zabbix en maakt een bestand met een regel erin.
Bijv .:
#!/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
of:
#!/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
om te ontsnappen aan een script dat op deze manier is verkregen, nietexit
– het zijn net shell-functies, enexit
verlaat de shell waar het script vandaan komt.source ./script
hetzelfde?.
ensource
zijn gelijk in bash. 2. we doneren ‘ Het is niet nodig./
te gebruiken voor de bestandsnaam als het ‘ in dezelfde directory staat. Het is oké om alleen dit uit te voeren:. script