2013-04-11 10 views
26

Próbuję uruchomić skrypt poprzez nodejs że robi:Jak uzyskać CWD (bieżący katalog roboczy) od nodejs procesu potomnego (w obu oknach i linuxish)

cd .. 
doSomethingThere[] 

Jednak, aby to zrobić , Muszę wykonać wiele procesów potomnych i przenieść stan środowiska między tymi procesami. Co chciałbym zrobić, to:

var exec = require('child_process').exec; 
var child1 = exec('cd ..', function (error, stdout, stderr) { 
    var child2 = exec('cd ..', child1.environment, function (error, stdout, stderr) { 
    }); 
}); 

lub co najmniej:

var exec = require('child_process').exec; 
var child1 = exec('cd ..', function (error, stdout, stderr) { 
    var child2 = exec('cd ..', {cwd: child1.process.cwd()}, function (error, stdout, stderr) { 
    }); 
}); 

Jak mogę to zrobić?

+3

Zajrzyj do włókien lub do jednej z wielu bibliotek wątków roboczych dla węzła; zaoszczędź sobie mnóstwo energii i skorzystaj z bibliotek, które już rozwiązały setki problemów, które napotkasz jak ten. – Kato

+0

@Kato Używam włókien. Nie ma to nic wspólnego z tym, o co pytam. Jeśli biblioteki wątków roboczych, o których mówisz, są w ogóle podobne, nie są w tym przypadku pomocne. –

Odpowiedz

30

rozpocząć dziecko z macierzystego dir jako CWD:

var exec = require('child_process').exec; 
var path = require('path') 

var parentDir = path.resolve(process.cwd(), '..'); 
exec('doSomethingThere', {cwd: parentDir}, function (error, stdout, stderr) { 
    // if you also want to change current process working directory: 
    process.chdir(parentDir); 
}); 

Aktualizacja: jeśli chcesz odzyskać CWD dziecka:

var fs = require('fs'); 
var os = require('os'); 
var exec = require('child_process').exec; 

function getCWD(pid, callback) { 
    switch (os.type()) { 
    case 'Linux': 
    fs.readlink('/proc/' + pid + '/cwd', callback); break; 
    case 'Darwin': 
    exec('lsof -a -d cwd -p ' + pid + ' | tail -1 | awk \'{print $9}\'', callback); 
    break; 
    default: 
    callback('unsupported OS'); 
    } 
} 

// start your child process 
// note that you can't do like this, as you launch shell process 
// and shell's child don't change it's cwd: 
// var child1 = exec('cd .. & sleep 1 && cd .. sleep 1'); 
var child1 = exec('some process that changes cwd using chdir syscall'); 

// watch it changing cwd: 
var i = setInterval(getCWD.bind(null, child1.pid, console.log), 100); 
child1.on('exit', clearInterval.bind(null, i));  
+0

Hej, Andrey, rozwiązuje to problem wymyślonego przykładu, który wymyśliłem, ale nadal nie odpowiada na główne pytanie, jak uzyskać katalog roboczy z procesu potomnego. –

+0

potrzebujesz procesu potomnego, aby zgłosić swój katalog roboczy? Początkowo jest ustawiony przez opcję 'cwd'. Jeśli musisz wiedzieć, co było przed wyjściem dziecka, wyślij je od dziecka przez wywołanie RPC (najprościej jest tylko wydrukować na standardowe wyjście) –

+0

Próbuję uruchomić dowolne polecenia powłoki, które mogą zawierać polecenia zmieniające cwd (np. "Płyta CD"). –

2

tylko myśl, jeśli wiesz procesie potomnym PID i zainstalowano pwdx (prawdopodobnie na Linuksie), możesz wykonać polecenie z węzła, aby uzyskać cwd dziecka.

+0

+1 Zdecydowanie brzmi jak działająca odpowiedź.Byłoby wspaniale, gdyby istniał sposób na zrobienie tego bez kłopotania się z narzędziami wiersza poleceń tho –

+1

Rozwiązanie OSX: 'OSX:' lsof -a -d cwd -p [pid] '. Na Linuksie zamiast pwdx można po prostu zrobić 'ls -l/proc/[pid]/cwd' (lub z węzła:' require ('fs'). ReadlinkSync ('/ proc/123456/cwd') ') –

+0

Świetny punkt Andrey. –

19

Jeśli chcesz uzyskać bieżący katalog roboczy bez korzystania z programów narzędziowych wiersza poleceń systemu operacyjnego, możesz użyć biblioteki testowej "testowanej przez battled-test", która streszcza te rzeczy za Ciebie, a pod spodem za pomocą procesów potomnych.

var sh = require("shelljs"); 
var cwd = sh.pwd(); 

Masz to, zmienna cwd przechowuje twój bieżący katalog roboczy niezależnie od tego, czy używasz Linuksa, Windowsa, czy freebsd.

1

Uważam, że najlepiej jest manipulować options.cwd między połączeniami do exec. w exec oddzwonienie this.pwd i this.cwd może dać ci efekt dźwigni dla twoich implementacji.

Powiązane problemy