Ubah direktori kerja dalam konteks shell saya saat ini saat menjalankan skrip Node

114

Saya mencoba untuk mengubah direktori kerja skrip Node.js saya ketika dijalankan dari skrip bin. Saya punya sesuatu seperti berikut:

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

Ketika saya kemudian menjalankan file ini dengan ./bin/nodefile, itu keluar, tetapi direktori kerja dari konteks shell saat ini tidak berubah. Saya juga mencoba shelljs , tetapi itu juga tidak berhasil.

Apa cara terbaik untuk melakukannya? Saya mengerti ini berfungsi tetapi ini hanya dalam proses terpisah.

Jonovono
sumber
bukti apa yang Anda miliki bahwa cwd tidak berubah? Ingat bahwa jalur yang digunakan di require () dan cwd adalah dua hal yang berbeda.
jeesty
Apakah ada cara untuk melakukan ini di Windows?
Phillip

Jawaban:

146

Cara yang benar untuk mengubah direktori sebenarnya dengan process.chdir(directory). Berikut contoh dari dokumentasinya :

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

Ini juga dapat diuji di Node.js REPL:

[monitor@s2 ~]$ node
> process.cwd()
'/home/monitor'
> process.chdir('../');
undefined
> process.cwd();
'/home'
hexacyanide
sumber
Ups. Ya, itu adalah perintah yang sebenarnya saya gunakan. Namun, ketika saya menggunakannya dalam skrip sederhana, tampaknya masih tidak berfungsi (setelah skrip keluar, saya masih di direktori lama) Jika saya memanggil process.cwd () dikatakan saya ada di direktori saya seharusnya tetapi saya terminal jika saya menelepon pwd mengatakan saya dalam sesuatu yang sebaliknya. Karena ini proses yang berbeda?
Jonovono
10
Metode ini mengubah direktori kerja saat ini dari proses tersebut , bukan shellnya. Sejauh yang saya tahu, mengubah cwd eksternal dari proses yang sedang berjalan cukup rumit dan tidak disarankan. Apa alasan Anda ingin melakukan ini?
hexacyanide
3
Hmm. Ok terima kasih. Alasan saya ingin melakukan ini adalah karena saya membuat aplikasi terminal untuk mengatur proyek saya. Jadi pada dasarnya saya ingin dapat membuat daftar proyek saya dan dengan mudah mengubah lokasi shell saat ini ke sana. Sekarang saya memikirkannya, saya akan melihat bagaimana z ( github.com/rupa/z ) melakukan ini. Meski itu dilakukan secara bash. Saya mungkin bisa melakukan ini di applescript?
Jonovono
@hexacyanide terima kasih telah menambahkan mengganggu karena perubahan tidak selaras
Eugen Sunic
33

Tidak ada metode bawaan untuk Node untuk mengubah CWD dari shell yang mendasari menjalankan proses Node.

Anda dapat mengubah direktori kerja saat ini dari proses Node melalui perintah process.chdir().

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

Ketika proses Node ada, Anda akan menemukan diri Anda kembali ke CWD tempat Anda memulai proses.

dthree
sumber
14

Apa yang Anda coba lakukan tidak mungkin. Alasan untuk ini adalah karena dalam sistem POSIX (Linux, OSX, dll), proses anak tidak dapat mengubah lingkungan proses induk. Ini termasuk memodifikasi direktori kerja proses induk dan variabel lingkungan.

Ketika Anda berada di baris perintah dan Anda pergi untuk mengeksekusi skrip Node Anda, proses Anda saat ini ( bash, zshapa pun) memunculkan proses baru yang memiliki lingkungannya sendiri, biasanya salinan lingkungan Anda saat ini (dimungkinkan untuk mengubahnya melalui panggilan sistem ; tetapi itu di luar cakupan balasan ini), memungkinkan proses tersebut melakukan apa pun yang perlu dilakukan dalam isolasi penuh. Saat subproses keluar, kontrol dikembalikan ke proses shell Anda, di mana lingkungan tidak terpengaruh.

Ada banyak alasan untuk ini, tetapi untuk satu, bayangkan Anda mengeksekusi skrip di latar belakang (melalui ./foo.js &) dan saat dijalankan, itu mulai mengubah direktori kerja Anda atau menimpa PATH. Itu akan menjadi mimpi buruk.

Jika Anda perlu melakukan beberapa tindakan yang mengharuskan mengubah direktori kerja shell Anda, Anda harus menulis fungsi di shell Anda. Misalnya, jika Anda menjalankan Bash, Anda dapat meletakkan ini di ~/.bash_profile:

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

dan kemudian hal keren ini bisa dilakukan:

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

Jika Anda perlu melakukan hal-hal yang lebih kompleks sebagai tambahan, Anda selalu dapat memanggil skrip nodejs dari fungsi itu.

Ini adalah satu-satunya cara Anda dapat mencapai apa yang Anda coba lakukan.

Spike Grobstein
sumber
10

Jawaban singkatnya: tidak (mudah?), Tetapi Anda dapat melakukan sesuatu yang sesuai dengan tujuan Anda.

Saya telah melakukan alat serupa (perintah kecil yang, memberikan deskripsi proyek, menetapkan lingkungan, jalur, direktori, dll.). Yang saya lakukan adalah mengatur semuanya dan kemudian menelurkan cangkang dengan:

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

Setelah eksekusi, Anda akan berada di shell dengan direktori baru (dan, dalam kasus saya, lingkungan). Tentu saja Anda dapat mengubah bash untuk shell apa pun yang Anda inginkan. Perbedaan utama dengan permintaan awal Anda adalah:

  • Ada proses tambahan, jadi ...
  • Anda harus menulis 'keluar' untuk kembali, dan kemudian ...
  • setelah ada, semua perubahan dibatalkan.

Namun, bagi saya, perbedaan itu diinginkan.

Evolusi
sumber