Script per modificare la directory corrente (cd, pwd)


44

Voglio eseguire uno script per cambiare semplicemente la directory di lavoro corrente:

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

Ma, dopo averlo eseguito, l'attuale pwd rimane invariato! Come lo posso fare?

Risposte:


63

È un comportamento previsto e già discusso più volte.

Lo script viene eseguito in una subshell e non può modificare la directory di lavoro della shell padre. I suoi effetti si perdono quando finisce.

Per modificare la directory in modo permanente è necessario eseguire il source dello script, come in

. ./script

8
@Sony: Nota che dovresti usare returnper scappare da uno script in questo modo, non exit- sono come funzioni di shell e exitusciranno dalla shell che ha originato lo script.
Charles Stewart,

@CharlesStewart In effetti, non ho familiarità con gli script di provenienza. Grazie!
Sony Santos,

5
è source ./scriptlo stesso?
amyassin,

2
@amyassin: sì, lo è
enzotib

2
1. .e sourcesono uguali in bash. 2. non è necessario utilizzare ./prima del nome file se si trova nella stessa directory. Va bene eseguire solo questo:. script
sobi3ch,

19

Per piccole attività come questa, invece di creare uno script, crea un alias come questo,

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

Dovresti aggiungerlo al tuo .bashrcfile, se lo desideri impostato per ogni shell interattiva.

Ora puoi eseguirlo come $ cdproj.


1
È inoltre possibile fare in modo che lo script faccia eco ai comandi da eseguire, quindi utilizzare eval `./script` o eval $(./script)per eseguire tali comandi. Questo è un approccio comune per i comandi che devono aggiornare l'ambiente della shell che invoca.
Keith Thompson,

2
Basta stare molto attenti a ciò che si ottiene se si intende seguire l' evalapproccio.
jw013,

13

Utilizzare exec bashalla fine

Uno script bash opera nel suo ambiente attuale o in quello dei suoi figli, ma mai nel suo ambiente genitore.

Tuttavia, questa domanda viene spesso posta perché si desidera essere lasciati al prompt di bash in una determinata directory dopo l'esecuzione di uno script bash da un'altra directory.

In tal caso, eseguire semplicemente un'istanza bash figlio alla fine dello script:

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

Questo crea una nuova subshell. Digitare exitper tornare alla prima shell in cui lo script è stato inizialmente avviato.


Meglio solo procurarsi lo script, come nella risposta accettata: l'uso execè in genere considerato l'ultima risorsa di un mascalzone .. :)
neuronet

1
questo trucco non funziona in debian 9 stretch.
vdegenne,

3
Questo è il modo sbagliato di procedere!
In pausa fino a nuovo avviso.

4
Dal momento che nessuno ha dettagliato i problemi con questo (ti sto guardando, @Dennis): (1) Ogni volta che esegui questo, crea un nuovo processo persistente bash. Fallo dieci o venti volte in una sessione e avrai accumulato da 11 a 21 processi bash. Ciò può influire sulle prestazioni e, se si tenta di terminare la sessione in modo pulito digitando exit(o Ctrl + D), è necessario farlo dalle 11 alle 21 volte. (2) Un altro svantaggio dell'uso di uno script eseguibile è che, se si impostano opzioni di shell (ad esempio,  dotglobo  globstar) nella sessione di shell interattiva, le si perderanno, poiché si avvia una nuova shell.
G-Man dice "Reinstate Monica" il

1
Ottima soluzione! Ho riscritto il mio alias in bash_profile, quindi ora è uno script memorizzato in un file separato. Uso lo script per passare a una cartella temporanea appena creata. E ora è ancora più facile avere una sessione bash temporanea. SRP in azione! Grazie!
artyom.razinov,

8

Mentre ci sono risposte che eseguono esattamente l'azione desiderata, un metodo più standard per tale scopo è quello di creare un collegamento simbolico:

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

Quindi è possibile cdaccedere alla directory utilizzando il nome proj:

cd proj

Questo metodo è più flessibile perché è possibile accedere ai file utilizzando il nome breve senza cd:

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


4

Dipende da cosa hai intenzione di fare, un'altra soluzione può essere quella di creare una funzione anziché uno script.

Esempio:

Crea una funzione in un file, diciamo /home/aidin/my-cd-script:

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

Quindi includilo nel tuo bashrco zshrcfile:

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

Ora puoi usarlo come un comando:

$ my-cd

0

Perché non usare "exec" cuciture per fare esattamente quello che desidero.

#!/bin/bash

cd someplace
exec bash

~/someplace

1
Fai attenzione alle cose che sembrano essere ciò che vuoi. (Un gigantesco cavallo di legno! Proprio quello che volevo!) Ogni volta che esegui questo, crea un nuovo e persistente processo di bash. Fallo dieci o venti volte in una sessione e avrai accumulato da 11 a 21 processi bash. Ciò può influire sulle prestazioni e, se si tenta di terminare la sessione in modo pulito digitando exit(o Ctrl + D), è necessario farlo dalle 11 alle 21 volte.
G-Man dice "Reinstate Monica" l'

Ho sicuramente potuto vedere dove sarebbe un problema. Per me, però, lo sto usando una volta, facendo il lavoro di cui ho bisogno e poi uscendo. Se questo è l'unico inconveniente con cui posso convivere. D'altra parte, se esiste una soluzione migliore, sono disposto a guardarla.
paul

La risposta di Aidin a questa domanda , usando una funzione shell, e la risposta di Sachin Divekar , usando un alias, sono (IMO) soluzioni migliori rispetto all'utilizzo di uno script. PS Un altro svantaggio dell'uso di uno script è che, se imposti delle opzioni di shell (ad esempio,  dotglobo  globstar), le perderai, perché stai avviando una nuova shell. ... (proseguendo)
G-Man dice "Reinstate Monica" il

(Segue) ... PPS Ho appena notato che si è, in fondo, ribadendo la risposta di Serge Stroobandt e dicendo '' Perché non fare questo? '' A  Pila di cambio ci aspettiamo risposte per fornire nuove idee e / o informazioni, e non solo discutere altre risposte.
G-Man dice "Reinstate Monica" il

-1

Puoi farlo usando una funzione o usando && Gli esempi seguenti installano Zabbix e creano un file con una linea al suo interno.

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

o:

#!/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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.