नोड स्क्रिप्ट चलाते समय मेरे वर्तमान शेल संदर्भ में कार्यशील निर्देशिका बदलें


114

मैं अपनी Node.js स्क्रिप्ट की वर्किंग डायरेक्टरी को तब बदलने की कोशिश कर रहा हूं जब इसे बिन स्क्रिप्ट से चलाया जाता है। मेरे पास कुछ इस तरह है:

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

जब मैं इस फ़ाइल को चलाता हूं, तो ./bin/nodefileयह बाहर निकल जाती है, लेकिन वर्तमान शेल संदर्भ की कार्यशील निर्देशिका नहीं बदली है। मैंने शैलज की भी कोशिश की है , लेकिन वह भी काम नहीं करता है।

इसे करने का बेहतरीन तरीका क्या है? मैं समझता हूं कि यह काम कर रहा है लेकिन यह सिर्फ एक अलग प्रक्रिया में है।


आपके पास क्या सबूत है कि cwd नहीं बदला? याद रखें कि आवश्यकता में प्रयुक्त पथ () और सीडब्ल्यूडी दो अलग-अलग चीजें हैं।
jeesty

क्या विंडोज में ऐसा करने का कोई तरीका है?
फिलिप

जवाबों:


146

निर्देशिकाओं को बदलने का सही तरीका वास्तव में है process.chdir(directory)। यहाँ प्रलेखन से एक उदाहरण है :

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

यह Node.js REPL में भी परीक्षण योग्य है:

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

उफ़। हां, यह वह आज्ञा है जिसका मैं वास्तव में उपयोग कर रहा हूं। हालाँकि, जब मैं इसे एक साधारण स्क्रिप्ट में उपयोग करता हूं तो यह अभी भी काम नहीं करता है (एक बार स्क्रिप्ट बाहर निकल जाने के बाद भी मैं पुरानी निर्देशिका में हूं) टर्मिनल अगर मैं pwd कहता हूं, मैं अन्यथा किसी चीज में हूं। क्योंकि यह एक अलग प्रक्रिया है?
जोनोवो 3

10
विधि प्रक्रिया की वर्तमान कार्यशील निर्देशिका को बदल देती है , न कि शेल को। जहां तक ​​मुझे पता है, एक रनिंग प्रोसेस के बाहरी cwd को बदलना काफी जटिल है और इसकी सिफारिश नहीं की जाती है। ऐसा करने के लिए आपके कारण क्या है?
हेक्सासैनाइड

3
हम्म। ठीक है धन्यवाद। वैसे मैं ऐसा करना चाहता हूं क्योंकि मैं अपनी परियोजनाओं के आयोजन के लिए एक टर्मिनल ऐप बना रहा हूं। इसलिए मूल रूप से मैं अपनी परियोजनाओं को सूचीबद्ध करना चाहता हूं और वर्तमान शेल स्थान को आसानी से बदल सकता हूं। अब जब मैं इसके बारे में सोचता हूं, तो मैं यह देखने जा रहा हूं कि z ( github.com/rupa/z ) यह कैसे करता है। यद्यपि यह बाश में किया जाता है। मैं शायद applescript में ऐसा कर सकता था?
जोनोवो

जोड़ने के लिए @hexacyanide धन्यवाद परेशान कर रहा था क्योंकि परिवर्तन संरेखित नहीं थे
यूजेन

33

नोड के लिए कोई अंतर्निहित पद्धति नहीं है जो नोड प्रक्रिया को चलाने वाले अंतर्निहित शेल के CWD को बदलने के लिए है।

आप कमांड के माध्यम से नोड प्रक्रिया की वर्तमान कार्यशील निर्देशिका को बदल सकते हैं ।process.chdir()

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

जब नोड प्रक्रिया मौजूद होती है, तो आप स्वयं को CWD में वापस पाएंगे जो आपने प्रक्रिया शुरू की थी।


14

आप जो करना चाह रहे हैं वह संभव नहीं है। इसका कारण यह है कि एक POSIX सिस्टम (लिनक्स, OSX, आदि) में, एक बच्चे की प्रक्रिया एक मूल प्रक्रिया के वातावरण को संशोधित नहीं कर सकती है। इसमें मूल प्रक्रिया की कार्यशील निर्देशिका और पर्यावरण चर को संशोधित करना शामिल है।

जब आप कमांडलाइन पर होते हैं और आप अपनी नोड स्क्रिप्ट को निष्पादित करने के लिए जाते हैं, तो आपकी वर्तमान प्रक्रिया ( bashऔर zsh, जो भी हो) एक नई प्रक्रिया को जन्म देती है, जिसमें इसका स्वयं का वातावरण होता है, आमतौर पर आपके वर्तमान वातावरण की प्रतिलिपि (सिस्टम कॉल के माध्यम से इसे बदलना संभव है) ; लेकिन यह इस उत्तर के दायरे से परे है), उस प्रक्रिया को पूर्ण अलगाव में करने के लिए जो कुछ भी करने की आवश्यकता है उसे करने की अनुमति देता है। जब उपप्रकार बाहर निकलता है, तो नियंत्रण को आपके शेल की प्रक्रिया में वापस सौंप दिया जाता है, जहां पर्यावरण प्रभावित नहीं हुआ है।

इसके कई कारण हैं, लेकिन एक के लिए, कल्पना करें कि आपने पृष्ठभूमि में एक स्क्रिप्ट निष्पादित की (के माध्यम से ./foo.js &) और जैसे-जैसे यह चलता गया, यह आपकी कार्यशील निर्देशिका को बदलना या आपके ओवरराइड करना शुरू कर दिया PATH। यह एक बुरा सपना होगा।

यदि आपको अपने शेल की कार्यशील निर्देशिका को बदलने के लिए कुछ क्रियाएं करने की आवश्यकता है, तो आपको अपने शेल में एक फ़ंक्शन लिखना होगा। उदाहरण के लिए, यदि आप बैश चला रहे हैं, तो आप इसे अपने में डाल सकते हैं ~/.bash_profile:

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

और फिर यह अच्छी बात है:

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

यदि आपको इसके अलावा और अधिक जटिल चीजें करने की आवश्यकता है, तो आप हमेशा उस फ़ंक्शन से अपने नोडज स्क्रिप्ट को कॉल कर सकते हैं।

यह एकमात्र तरीका है जिससे आप वह कर सकते हैं जो आप करने की कोशिश कर रहे हैं।


10

संक्षिप्त उत्तर: नहीं (आसान?) तरीका है, लेकिन आप कुछ ऐसा कर सकते हैं जो आपके उद्देश्य को पूरा करे।

मैंने एक समान टूल (एक छोटा कमांड, जो किसी प्रोजेक्ट का विवरण, पर्यावरण, पथ, निर्देशिका, आदि सेट करता है) किया है। मैं जो कुछ भी करता हूं, वह सब कुछ सेट करता है और फिर एक खोल के साथ:

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

निष्पादन के बाद, आप नई निर्देशिका (और, मेरे मामले में, पर्यावरण) के साथ एक शेल पर होंगे। बेशक आप जो भी शेल पसंद करते हैं उसके लिए बैश को बदल सकते हैं। आपने जो मूल रूप से मांगा था, उसके साथ मुख्य अंतर:

  • एक अतिरिक्त प्रक्रिया है, इसलिए ...
  • आपको वापस आने के लिए 'बाहर' लिखना होगा, और फिर ...
  • मौजूदा के बाद, सभी परिवर्तन पूर्ववत हैं।

हालांकि, मेरे लिए, कि मतभेद वांछनीय हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.