Thay đổi thư mục làm việc trong ngữ cảnh shell hiện tại của tôi khi chạy tập lệnh Node


113

Tôi đang cố gắng thay đổi thư mục làm việc của tập lệnh Node.js khi nó được chạy từ tập lệnh bin. Tôi có một cái gì đó như sau:

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

Sau đó, khi tôi chạy tệp này với ./bin/nodefile, tệp sẽ thoát, nhưng thư mục làm việc của ngữ cảnh trình bao hiện tại không thay đổi. Tôi cũng đã thử shelljs , nhưng điều đó cũng không hoạt động.

Cách tốt nhất để làm việc này là gì? Tôi hiểu nó đang hoạt động nhưng nó chỉ trong một quá trình riêng biệt.


bạn có bằng chứng nào cho thấy cwd không thay đổi? Hãy nhớ rằng các đường dẫn được sử dụng trong request () và cwd là hai thứ khác nhau.
jeesty

Có cách nào để thực hiện việc này trong Windows không?
Phillip

Câu trả lời:


145

Cách chính xác để thay đổi thư mục thực sự là với process.chdir(directory). Đây là một ví dụ từ tài liệu :

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

Điều này cũng có thể kiểm tra được trong Node.js REPL:

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

Giáo sư. Ya, đó là lệnh tôi thực sự đang sử dụng. Tuy nhiên, khi tôi sử dụng nó trong một tập lệnh đơn giản, nó dường như vẫn không hoạt động (khi tập lệnh thoát ra, tôi vẫn ở trong thư mục cũ) Nếu tôi gọi process.cwd (), nó cho biết tôi đang ở trong thư mục mà tôi nên ở thiết bị đầu cuối nếu tôi gọi pwd nói rằng tôi đang ở trong một cái gì đó khác. Bởi vì nó là một quá trình khác nhau?
Jonovono

10
Phương thức này thay đổi thư mục làm việc hiện tại của tiến trình , không thay đổi trình bao. Theo như tôi biết, việc thay đổi cwd bên ngoài của một tiến trình đang chạy là khá phức tạp và không được khuyến khích. Lý do bạn muốn làm điều này là gì?
hexacyanide

3
Hừ! Được rồi cảm ơn. Lý do tôi muốn làm điều này là vì tôi đang tạo một ứng dụng đầu cuối để tổ chức các dự án của mình. Vì vậy, về cơ bản tôi muốn có thể liệt kê các dự án của mình và dễ dàng thay đổi vị trí shell hiện tại thành đó. Bây giờ tôi nghĩ về nó, tôi sẽ xem xét cách z ( github.com/rupa/z ) thực hiện điều này. Mặc dù điều đó được thực hiện trong bash. Tôi có thể làm điều này trong Applecript?
Jonovono

@hexacyanide cảm ơn bạn đã thêm làm phiền vì những thay đổi không phù hợp
Eugen Sunic

33

Không có phương pháp cài sẵn nào để Node thay đổi CWD của lớp vỏ bên dưới đang chạy quá trình Node.

Bạn có thể thay đổi thư mục làm việc hiện tại của tiến trình Node thông qua lệnh process.chdir().

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

Khi quy trình Node tồn tại, bạn sẽ thấy mình trở lại CWD mà bạn đã bắt đầu quy trình.


14

Những gì bạn đang cố gắng làm là không thể. Lý do cho điều này là trong hệ thống POSIX (Linux, OSX, v.v.), một quy trình con không thể sửa đổi môi trường của một quy trình mẹ. Điều này bao gồm sửa đổi thư mục làm việc của quy trình mẹ và các biến môi trường.

Khi bạn ở trên dòng lệnh và bạn thực thi tập lệnh Node của mình, quy trình hiện tại của bạn ( bash, zshbất cứ điều gì) tạo ra một quy trình mới có môi trường riêng của nó, thường là bản sao của môi trường hiện tại của bạn (có thể thay đổi điều này thông qua lệnh gọi hệ thống ; nhưng điều đó nằm ngoài phạm vi của câu trả lời này), cho phép quá trình đó làm bất cứ điều gì cần làm một cách hoàn toàn riêng biệt. Khi quy trình con thoát ra, quyền kiểm soát được trao lại cho quy trình của shell của bạn, nơi môi trường không bị ảnh hưởng.

Có rất nhiều lý do cho điều này, nhưng đối với một, hãy tưởng tượng rằng bạn thực thi một tập lệnh trong nền (qua ./foo.js &) và khi nó chạy, nó bắt đầu thay đổi thư mục làm việc của bạn hoặc ghi đè của bạn PATH. Đó sẽ là một cơn ác mộng.

Nếu bạn cần thực hiện một số hành động yêu cầu thay đổi thư mục làm việc của shell, bạn sẽ cần viết một hàm trong shell của mình. Ví dụ: nếu bạn đang chạy Bash, bạn có thể đặt điều này vào ~/.bash_profile:

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

và sau đó điều thú vị này có thể làm được:

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

Ngoài ra, nếu bạn cần thực hiện những việc phức tạp hơn, bạn luôn có thể gọi tập lệnh nodejs của mình từ hàm đó.

Đây là cách duy nhất bạn có thể hoàn thành những gì bạn đang cố gắng làm.


10

Câu trả lời ngắn gọn: không (dễ?), Nhưng bạn có thể làm điều gì đó phục vụ mục đích của mình.

Tôi đã thực hiện một công cụ tương tự (một lệnh nhỏ, đưa ra mô tả về một dự án, thiết lập môi trường, đường dẫn, thư mục, v.v.). Những gì tôi làm là thiết lập mọi thứ và sau đó tạo ra một shell với:

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

Sau khi thực thi, bạn sẽ ở trên một trình bao với thư mục mới (và trong trường hợp của tôi là môi trường). Tất nhiên bạn có thể thay đổi bash cho bất kỳ shell nào bạn thích. Sự khác biệt chính với những gì bạn yêu cầu ban đầu là:

  • Có một quy trình bổ sung, vì vậy ...
  • bạn phải viết 'exit' để quay lại, và sau đó ...
  • sau khi hiện có, tất cả các thay đổi sẽ được hoàn tác.

Tuy nhiên, đối với tôi, sự khác biệt đó là điều đáng mơ ước.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.