Düğüm betiğini çalıştırırken mevcut kabuk bağlamımdaki çalışma dizinini değiştir


114

Bir bin betiğinden çalıştırıldığında Node.js betiğimin çalışma dizinini değiştirmeye çalışıyorum. Aşağıdaki gibi bir şeyim var:

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

Daha sonra bu dosyayı birlikte çalıştırdığımda ./bin/nodefileçıkılıyor, ancak mevcut kabuk bağlamının çalışma dizini değişmedi. Ben de shelljs denedim , ama bu da çalışmıyor.

Bunu yapmanın en iyi yolu nedir? Çalıştığını anlıyorum ama sadece ayrı bir süreçte.


cwd'nin değişmediğine dair hangi kanıtınız var? Require () ve cwd'de kullanılan yolların iki farklı şey olduğunu unutmayın.
jeesty

Bunu Windows'ta yapmanın bir yolu var mı?
Phillip

Yanıtlar:


146

Dizinleri değiştirmenin doğru yolu aslında ile process.chdir(directory). Belgelerden bir örnek :

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

Bu, Node.js REPL'de de test edilebilir:

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

Hata. Evet, aslında kullandığım komut bu. Ancak, onu basit bir komut dosyasında kullandığımda hala çalışmıyor gibi görünüyor (komut dosyası çıktıktan sonra hala eski dizindeyim) process.cwd () 'yi çağırırsam, dizinde olduğumu söylüyor olmalıyım ama benim terminal pwd ararsam başka bir şeyde olduğumu söylüyor. Farklı bir süreç olduğu için mi?
Jonovono

10
Yöntem , kabuğun değil, sürecin geçerli çalışma dizinini değiştirir . Bildiğim kadarıyla, çalışan bir sürecin harici cwd'sini değiştirmek oldukça karmaşıktır ve önerilmez. Bunu yapmak istemenizin nedeni nedir?
hekzasiyanür

3
Hmm. Tamam teşekkürler. Bunu yapmak istememin sebebi, projelerimi organize etmek için bir terminal uygulaması yapıyorum. Bu yüzden temelde projelerimi listeleyebilmek ve mevcut kabuk konumunu buna kolayca değiştirebilmek istiyorum. Şimdi düşünüyorum da, z ( github.com/rupa/z ) 'nın bunu nasıl yaptığına bakacağım . Bu Bash'de yapılmasına rağmen. Bunu el yazısıyla yapabilir miyim?
Jonovono

@hexacyanide eklediğiniz için teşekkürler rahatsız ediciydi çünkü değişiklikler uyumlu değildi
Eugen Sunic

33

Node'un , Node işlemini çalıştıran temel kabuğun CWD'sini değiştirmesi için yerleşik bir yöntem yoktur .

Sen edebilirsiniz geçerli çalışma dizinini değiştirmek Düğüm süreci komutu ile process.chdir().

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

Düğüm süreci mevcut olduğunda, kendinizi işlemi başlattığınız CWD'de bulacaksınız.


14

Yapmaya çalıştığınız şey mümkün değil. Bunun nedeni, bir POSIX sisteminde (Linux, OSX, vb.), Bir alt sürecin bir üst sürecin ortamını değiştirememesidir. Bu, üst sürecin çalışma dizinini ve ortam değişkenlerini değiştirmeyi içerir.

Komut satırındayken ve Düğüm betiğinizi çalıştırmaya gittiğinizde, mevcut işleminiz ( bash, zshne olursa olsun) kendi ortamına sahip yeni bir işlem oluşturur, tipik olarak mevcut ortamınızın bir kopyası (bunu sistem çağrıları yoluyla değiştirmek mümkündür. ; ancak bu, bu yanıtın kapsamı dışındadır), bu sürecin yapması gereken her şeyi tamamen izole bir şekilde yapmasına izin verir. Alt süreçten çıkıldığında, kontrol, ortamın etkilenmediği kabuğunuzun sürecine geri verilir.

Bunun pek çok nedeni var, ancak birincisi, arka planda (aracılığıyla ./foo.js &) bir komut dosyası çalıştırdığınızı ve çalışırken, çalışma dizininizi değiştirmeye veya PATH. Bu bir kabus olur.

Kabuğunuzun çalışma dizininizi değiştirmeyi gerektiren bazı eylemler gerçekleştirmeniz gerekiyorsa, kabuğunuza bir işlev yazmanız gerekir. Örneğin, Bash çalıştırıyorsanız, bunu şunlara koyabilirsiniz ~/.bash_profile:

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

ve sonra bu harika şey yapılabilir:

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

Ek olarak daha karmaşık şeyler yapmanız gerekiyorsa, nodejs betiğinize her zaman bu işlevden seslenebilirsiniz.

Yapmaya çalıştığınız şeyi başarmanın tek yolu budur.


10

Kısa cevap: (kolay?) Bir yol yok, ama amacınıza hizmet eden bir şey yapabilirsiniz.

Benzer bir araç yaptım (bir projenin açıklaması verildiğinde ortamı, yolları, dizinleri vb. Ayarlayan küçük bir komut). Yaptığım şey her şeyi ayarlamak ve ardından şunlarla bir kabuk oluşturmak:

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

Yürütmeden sonra, yeni dizinle (ve benim durumumda ortamla) bir kabukta olacaksınız. Elbette, tercih ettiğiniz kabuk için bash'ı değiştirebilirsiniz. Başlangıçta istediğiniz şeyle temel farklılıklar şunlardır:

  • Ek bir süreç var, yani ...
  • geri dönmek için 'çıkış' yazmalısın ve sonra ...
  • mevcut olduktan sonra tüm değişiklikler geri alınır.

Ancak benim için bu farklılıklar arzu edilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.