Cambia la directory di lavoro nel mio attuale contesto di shell quando esegui lo script Node


114

Sto cercando di cambiare la directory di lavoro del mio script Node.js quando viene eseguito da uno script bin. Ho qualcosa di simile al seguente:

#!/usr/bin/env node
process.chdir('/Users')

Quando poi eseguo questo file con ./bin/nodefile, esce, ma la directory di lavoro del contesto corrente della shell non è cambiata. Ho anche provato shelljs , ma neanche quello funziona.

Qual è il modo migliore per farlo? Capisco che funzioni, ma è solo in un processo separato.


che prove hai che il cwd non sia cambiato? Ricorda che i percorsi usati in require () e cwd sono due cose diverse.
jeesty

C'è un modo per farlo in Windows?
Phillip

Risposte:


146

Il modo corretto per cambiare directory è in realtà con process.chdir(directory). Ecco un esempio dalla documentazione :

console.log('Starting directory: ' + process.cwd());
try {
  process.chdir('/tmp');
  console.log('New directory: ' + process.cwd());
}
catch (err) {
  console.log('chdir: ' + err);
}

Questo è anche testabile nel REPL Node.js:

[monitor@s2 ~]$ node
> process.cwd()
'/home/monitor'
> process.chdir('../');
undefined
> process.cwd();
'/home'

Ops. Sì, questo è il comando che sto effettivamente usando. Tuttavia, quando lo uso in uno script semplice, sembra ancora non funzionare (una volta che lo script è uscito sono ancora nella vecchia directory) Se chiamo process.cwd () dice che sono nella directory che dovrei essere ma il mio terminale se chiamo pwd dice che sono in qualcosa di diverso. Perché è un processo diverso?
Jonovono

10
Il metodo cambia la directory di lavoro corrente del processo , non la shell. Per quanto ne so, modificare il cwd esterno di un processo in esecuzione è piuttosto complesso e non è raccomandato. Qual è il motivo per cui vuoi farlo?
esacianide

3
Hmm. Ok grazie. Bene, il motivo per cui voglio farlo è perché sto creando un'app terminale per organizzare i miei progetti. Quindi fondamentalmente voglio essere in grado di elencare i miei progetti e cambiare facilmente la posizione corrente della shell in quella. Ora che ci penso, esaminerò come z ( github.com/rupa/z ) fa questo. Anche se viene fatto in bash. Potrei forse farlo in MeleScritt?
Jonovono

@hexacyanide grazie per l'aggiunta è stato fastidioso perché le modifiche non erano allineate
Eugen Sunic il

33

Non esiste un metodo integrato per Node per modificare il CWD della shell sottostante che esegue il processo Node.

È possibile modificare la directory di lavoro corrente del processo Node tramite il comando process.chdir().

var process = require('process');
process.chdir('../');

Quando il processo Node esiste, ti ritroverai nel CWD in cui hai avviato il processo.


14

Quello che stai cercando di fare non è possibile. La ragione di ciò è che in un sistema POSIX (Linux, OSX, ecc.), Un processo figlio non può modificare l'ambiente di un processo genitore. Ciò include la modifica della directory di lavoro e delle variabili di ambiente del processo genitore.

Quando si è sulla riga di comando e si va ad eseguire il nodo lo script, il processo in corso ( bash, zsh, a prescindere) genera un nuovo processo, che ha il proprio ambiente, in genere una copia del vostro ambiente corrente (è possibile cambiare questa via le chiamate di sistema ; ma questo va oltre lo scopo di questa risposta), consentendo a quel processo di fare tutto ciò che deve fare in completo isolamento. Quando il sottoprocesso esce, il controllo viene restituito al processo della shell, dove l'ambiente non è stato influenzato.

Ci sono molte ragioni per questo, ma per uno, immagina di aver eseguito uno script in background (tramite ./foo.js &) e mentre veniva eseguito, ha iniziato a cambiare la tua directory di lavoro o sovrascrivere la tua PATH. Sarebbe un incubo.

Se è necessario eseguire alcune azioni che richiedono la modifica della directory di lavoro della shell, sarà necessario scrivere una funzione nella shell. Ad esempio, se stai utilizzando Bash, potresti inserire questo nel tuo ~/.bash_profile:

do_cool_thing() {
  cd "/Users"
  echo "Hey, I'm in $PWD"
}

e poi questa cosa interessante è fattibile:

$ pwd
/Users/spike
$ do_cool_thing
Hey, I'm in /Users
$ pwd
/Users

Se hai bisogno di fare cose più complesse in aggiunta, puoi sempre chiamare il tuo script nodejs da quella funzione.

Questo è l'unico modo in cui puoi realizzare ciò che stai cercando di fare.


10

Risposta breve: no (facile?), Ma puoi fare qualcosa che serve al tuo scopo.

Ho fatto uno strumento simile (un piccolo comando che, data una descrizione di un progetto, imposta ambiente, percorsi, directory, ecc.). Quello che faccio è impostare tutto e quindi generare una shell con:

spawn('bash', ['-i'], {
  cwd: new_cwd,
  env: new_env,
  stdio: 'inherit'
});

Dopo l'esecuzione, sarai su una shell con la nuova directory (e, nel mio caso, l'ambiente). Ovviamente puoi cambiare bash per qualunque shell preferisci. Le principali differenze con quanto richiesto originariamente sono:

  • C'è un processo aggiuntivo, quindi ...
  • devi scrivere 'exit' per tornare, e poi ...
  • dopo essere esistito, tutte le modifiche vengono annullate.

Tuttavia, per me, queste differenze sono auspicabili.

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.