2010-03-03 28 views
18

Come il titolo lo rivela, stiamo scrivendo un'utilità di shell in stile Unix U che dovrebbe essere invocato (nella maggior parte dei casi) da bash.Come si imposta la directory di lavoro del processo principale?

In che modo esattamente U cambia la directory di lavoro di bash (o parent in generale)?

P.S. L'utilità shell chdir riesce a fare esattamente la stessa cosa, quindi ci deve essere un modo programmatico per ottenere l'effetto.

+0

Vedi anche http://stackoverflow.com/questions/255414/why-doesnt-cd-work-in-a-bash-shell-script – tripleee

risposta

28

Non farlo.

FILE *p; 
char cmd[32]; 
p = fopen("/tmp/gdb_cmds", "w"); 
fprintf(p, "call chdir(\"..\")\ndetach\nquit\n"); 
fclose(p); 
sprintf(cmd, "gdb -p %d -batch -x /tmp/gdb_cmds", getppid()); 
system(cmd); 

Sarà probabilmente lavoro, anche se nota che il comando di Bash pwd viene memorizzato nella cache e non se ne accorgerà.

+10

+1 per "non fare questo" – Vlad

+0

sarebbe possibile invocare allo stesso modo una procedura che costringerebbe Bash a controllare (possibilmente modificato) la directory di lavoro? – user285728

+0

@coderodde Guardando attraverso il codice sorgente Bash, è evidente che 'resetpwd (" ")' dopo 'chdir (" .. ")' si prenderà cura del pwd memorizzato nella cache. Ma non hai letto "Non farlo"? Seriamente, no. – ephemient

6

Non esiste un modo "legale" per influenzare la directory corrente del processo principale altro che richiede semplicemente al processo padre di modificarlo autonomamente.

chdir che cambia la directory negli script di bash non è un'utilità esterna, è un comando incorporato.

3

Il comando chdir è una shell incorporata, quindi ha accesso diretto alla directory di lavoro della shell che la esegue. I gusci sono generalmente abbastanza bravi a proteggersi dagli effetti degli script, dando al bambino una copia copia dell'ambiente di lavoro della shell stessa. Quando il processo secondario termina, l'ambiente utilizzato viene eliminato.

Una cosa che puoi fare è creare una sceneggiatura. Questo ti permette di cambiare la directory perché in pratica stai dicendo alla shell di eseguire i comandi dal file come se li avessi inseriti direttamente. Ad esempio, non stai lavorando su una copia dell'ambiente della shell, stai lavorando direttamente su di esso, quando fai il sourcing.

1

Nel caso in cui si esegue il guscio in modo interattivo e la directory di destinazione è statico, si può semplicemente mettere un alias nel vostro ~/.bashrc del file:

alias cdfoo='cd theFooDir' 

Quando si tratta di script di shell non interattiva, è possibile creare una protocollo tra lo script Bash parentale e lo script Bash figlio. Un metodo per implementare questo è lasciare che lo script figlio salvi il percorso in un file (come ~/.new-work-dir). Al termine del processo figlio, il processo genitoriale dovrà leggere questo file (come cd `cat ~/.new-work-dir`).

Se si prevede di utilizzare la regola citata nel paragrafo precedente molto spesso, suggerisco di scaricare il codice sorgente Bash e correggerlo in modo che cambi automaticamente la directory di lavoro al contenuto di dopo ogni esecuzione di un comando . Nella patch, potresti anche implementare un comando integrato Bash completamente nuovo che si adatta alle tue esigenze e implementa il protocollo che vuoi implementare (questo nuovo comando probabilmente non sarà accettato dai manutentori di Bash). Tuttavia, il patching funziona per uso personale e per l'uso in una comunità più piccola.

3

Il modo in cui I solved this deve avere un alias di shell che chiama lo script e genera un file scritto dallo script.Così, per esempio,

function waypoint { 
    python "$WAYPOINT_DIRECTORY"/waypoint.py [email protected] && 
    source ~/.config/waypoint/scratch.sh 
    cat /dev/null > ~/.config/waypoint/scratch.sh 
} 

e waypoint.py crea scratch.sh per assomigliare

cd /some/directory 

Questo è ancora una brutta cosa.

4

Esattamente come hai potuto cambiare la directory di lavoro di bash (o genitore in generale)?

È non possibile utilizzando qualsiasi modo "accettabile". Con accettabili, voglio dire "senza oltraggiosamente l'hacking del sistema (utilizzando gdb per esempio)";)

Più seriamente, quando l'utente lancia un eseguibile, il processo figlio verrà eseguito nella sua proprio ambiente, che è principalmente un copia del suo ambiente genitore. Questo ambiente contiene "variabili d'ambiente" e la "directory di lavoro corrente", solo per citarne uno.

Ovviamente, un processo può modificare il proprio ambiente proprio con lo . Ad esempio per cambiare la sua directory di lavoro (come quando si è cd xxx nella propria shell). Ma dal momento che questo ambiente è un copia, ciò non modifica in alcun modo l'ambiente del genitore. E non esiste un modo standard per modificare l'ambiente genitore.


Come nota, questo è il motivo cd ("chdir") è un comando shell interno, e non un esterno utilità . Se così fosse, non sarebbe in grado di cambiare la directory di lavoro della shell.

Problemi correlati