Script pentru a schimba directorul curent (cd, pwd)

Vreau să rulez un script pentru a schimba pur și simplu directorul de lucru curent:

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

Dar, după ce îl rulez, pwd-ul curent rămâne neschimbat! Cum pot face asta?

Răspuns

Este un comportament așteptat. Scriptul este rulat într-un subshell și nu poate schimba directorul de lucru al shell-ului părinte. Efectele sale se pierd când se termină.

Pentru a schimba definitiv directorul curent al shell-ului, ar trebui să utilizați comanda source, de asemenea, aliasată pur și simplu ca ., care rulează un script în mediul shell actual în loc de un shell secundar.

Următoarele comenzi sunt identice:

. script 

sau

source script 

Comentarii

  • @Sony: Rețineți că ar trebui să utilizați return pentru a scăpa de un script obținut în acest mod, nu exit – sunt ca niște funcții shell și exit va ieși de la shell-ul care a obținut scriptul.
  • @CharlesStewart De fapt, nu ‘ nu sunt familiarizat cu scripturile provenite. Mulțumesc!
  • este source ./script același?
  • @amyassin: da, este
  • 1. . și source sunt egale în bash. 2. nu ‘ nu trebuie să utilizați ./ înainte de numele fișierului dacă ‘ este în același director. Este ok să rulați doar acest lucru: . script

Răspuns

Pentru sarcini mici precum aceasta, în loc să creați un script, creați un alias ca acesta,

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

Ar trebui să adăugați acest lucru la .bashrc, dacă doriți ca acesta să fie setat pentru fiecare shell interactiv.

Acum puteți rula acest lucru ca $ cdproj.

Comentarii

  • De asemenea, puteți avea scriptul să răsune comenzile care urmează să fie executate, apoi să utilizați eval `./script` sau eval $(./script) pentru a executa acele comenzi. Aceasta este o abordare obișnuită pentru comenzile care trebuie să actualizeze mediul shell invocator ‘.
  • Doar aveți mare grijă la ceea ce produceți dacă doriți să mergeți abordarea eval.

Răspuns

Utilizați exec bash la sfârșit

Un script bash funcționează pe mediul său actual sau pe cel al copiilor săi, dar niciodată pe mediu părinte.

Cu toate acestea, această întrebare este adesea pusă deoarece se dorește lăsat la bash prompt într-un anumit director după executarea a unui script bash dintr-un alt director.

Dacă acesta este cazul, pur și simplu executați o instanță bash copil la sfârșit din script:

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

Aceasta creează un sub-shell nou. Tastați Ctrl + D sau exit pentru a reveni la primul shell unde a fost inițial început scriptul.

Actualizați

Cel puțin cu versiunile mai noi de bash, exec de pe ultima linie nu mai este necesară. Mai mult, scriptul poate fi făcut să funcționeze cu orice shell preferat utilizând variabila de mediu $SHELL. Acest lucru oferă apoi:

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

Comentarii

  • Mai bine să sursați doar scriptul, ca în răspunsul acceptat : utilizarea exec este de obicei considerată ultima soluție a unui ticălos .. 🙂
  • acest truc nu ‘ t lucrați în secțiunea debian 9.
  • Acesta este un mod greșit de urmat!
  • Deoarece nimeni nu a detaliat problemele cu acest lucru (mă uit la tine, @Dennis): (1) De fiecare dată când executați acest lucru, acesta creează un nou proces de bash persistent. Faceți acest lucru de zece sau douăzeci de ori într-o sesiune și veți avea între 11 și 21 de procese bash acumulate. Acest lucru poate afecta performanța și, dacă încercați să încheiați sesiunea curat, tastând exit (sau Ctrl + D), va trebui să faceți acest lucru de 11 până la 21 de ori. (2) Un alt dezavantaj al utilizării unui script executabil este acela că, dacă setați opțiuni de shell (de exemplu, dotglob sau globstar) în sesiune shell interactivă, le veți pierde, deoarece începeți un shell nou.
  • Soluție foarte frumoasă! Am ‘ am rescris aliasul meu în bash_profile, deci acum este un script stocat într-un fișier separat. Folosesc scriptul pentru a merge la un folder temporar nou creat. Și acum este și mai ușor să aveți o sesiune temporară de bash. SRP în acțiune! Mulțumiri!

Răspuns

Deși există răspunsuri care fac acțiunea exactă dorită, o metodă mai standard pentru astfel de scopul este de a crea o legătură simbolică:

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

Apoi ați putea cd la director folosind numele proj:

cd proj 

Această metodă este mai flexibilă deoarece puteți accesa fișiere folosind numele scurt fără cd:

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

Răspuns

Depinde de ceea ce „o să fac, o altă soluție poate fi crearea unei funcții în locul unui script.

Exemplu:

Creați o funcție într-un fișier, să spunem /home/aidin/my-cd-script:

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

Apoi includeți-l în bashrc sau zshrc fișier:

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

Acum îl puteți folosi ca o comandă:

$ my-cd 

Răspuns

Dacă schimbați între directoarele îndepărtate din sistemul de fișiere. Voi recomanda autojump .

Răspuns

Pentru mine cea mai convenabilă și flexibilă abordare a fost un amestec de alias și script:

creează un script cu logică arbitrară

Aici creez un script care se schimbă într-un director și activează mediul python adecvat. Locația scripturilor este exemplară în /path/to/workon_myproj.sh.

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

creați un alias care generează scriptul

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

Adăugați definiția aliasului în fișierul de pornire shell corespunzător, de ex. .profile, .bashrc sau .zshrc.

rezultat

Acum puteți pur și simplu să executați workon_myproj într-un shell care va sursa conținutul scriptului în directorul dorit.

extensibilitate

Puteți să vă îmbunătățiți scriptul pentru a lua un argument astfel încât să funcționeze cu mai multe proiecte într-un anumit director de lucru sau să îl combinați cu un git pull pentru a obține imediat cele mai recente modificări și așa pe … toate lucrurile pe care le faceți în cazul plăcii cazanului atunci când continuați să lucrați la un anumit proiect.

Răspundeți

De ce să nu folosiți ” exec „se pare să faci exact ceea ce îmi doresc.

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

Comentarii

  • Ferește-te de lucrurile care par a fi ceea ce vrei. (Un cal uriaș de lemn! Exact ceea ce îmi doream!) De fiecare dată când rulați acest lucru, creează un nou proces de bash persistent. Faceți-o de zece sau douăzeci de ori într-o sesiune și veți avea între 11 și 21 de procese bash stivuite. Acest lucru poate afecta performanța și, dacă încercați să încheiați sesiunea curat, tastând exit (sau Ctrl + D), va trebui să faceți acest lucru de 11 până la 21 de ori.
  • Cu siguranță am putut vedea unde ar fi o problemă. Pentru mine, deși ‘ îl folosesc o singură dată, fac treaba de care am nevoie și apoi ies. Dacă acest ‘ este singurul dezavantaj poate trăi cu asta. Pe de altă parte, dacă există o soluție mai bună, sunt ‘ dispus să o privesc.
  • Răspunsul lui Aidin la această întrebare , utilizând o funcție shell și Răspunsul lui Sachin Divekar , folosind un alias, sunt soluții (IMO) mai bune decât utilizarea unui script . P.S. Un alt dezavantaj al utilizării unui script este că, dacă setați opțiuni de shell (de ex., dotglob sau globstar), le veți pierde, pentru că începi o nouă coajă. … (Continuare)
  • (Continuare) … P.P.S. Tocmai am observat că, practic, reiterați răspunsul lui Serge Stroobandt și spuneți „De ce nu faceți acest lucru? La Stack Exchange ne așteptăm ca răspunsurile să ofere idei noi și / sau informații și nu doar să discutăm alte răspunsuri.

Răspuns

Acesta combină răspunsul de Serge cu un răspuns fără legătură de David . Schimbă directorul și apoi, în loc să forțeze un shell bash, acesta lansează shell-ul implicit al utilizatorului . Cu toate acestea, necesită ambele getent și /etc/passwd pentru a detecta shell-ul implicit.

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

Desigur, acest lucru are încă aceeași deficiență în crearea unui shell imbricat.

Răspuns

Puteți face acest lucru folosind o funcție sau folosind & & Exemplele de mai jos instalează Zabbix și creează un fișier cu o linie în interior.

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 

sau:

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

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *