Script om de huidige directory (cd, pwd) te wijzigen

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

  • @Sony: houd er rekening mee dat u return om te ontsnappen aan een script dat op deze manier is verkregen, niet exit – het zijn net shell-functies, en exit verlaat de shell waar het script vandaan komt.
  • @CharlesStewart In feite ben ik ‘ niet bekend met de scripts die afkomstig zijn. Dank je!
  • is source ./script hetzelfde?
  • @amyassin: ja, het is
  • 1. . en source 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

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` of eval $(./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 of globstar) 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 of globstar), 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 

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *