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
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`
saueval $(./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
sauglobstar
) î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
sauglobstar
), 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
return
pentru a scăpa de un script obținut în acest mod, nuexit
– sunt ca niște funcții shell șiexit
va ieși de la shell-ul care a obținut scriptul.source ./script
același?.
șisource
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