เปลี่ยนไดเร็กทอรีการทำงานในบริบทเชลล์ปัจจุบันของฉันเมื่อรัน Node script


114

ฉันกำลังพยายามเปลี่ยนไดเร็กทอรีการทำงานของสคริปต์ Node.js ของฉันเมื่อเรียกใช้จากสคริปต์ bin ฉันมีสิ่งต่อไปนี้:

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

เมื่อฉันเรียกใช้ไฟล์นี้ด้วยไฟล์./bin/nodefileจะออก แต่ไดเร็กทอรีการทำงานของบริบทเชลล์ปัจจุบันไม่เปลี่ยนแปลง ฉันได้ลองใช้shelljsแล้ว แต่ก็ไม่ได้ผลเช่นกัน

วิธีที่ดีที่สุดในการทำคืออะไร? ฉันเข้าใจว่ามันใช้งานได้ แต่อยู่ในกระบวนการแยกต่างหาก


คุณมีหลักฐานอะไรที่แสดงว่า cwd ไม่เปลี่ยนแปลง โปรดจำไว้ว่าเส้นทางที่ใช้ใน require () และ cwd เป็นสองสิ่งที่แตกต่างกัน
jeesty

มีวิธีดำเนินการใน Windows หรือไม่?
Phillip

คำตอบ:


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'

อ๊ะ. ใช่นั่นคือคำสั่งที่ฉันใช้จริง อย่างไรก็ตามเมื่อฉันใช้มันในสคริปต์ธรรมดาดูเหมือนว่าจะไม่ทำงาน (เมื่อสคริปต์ออกฉันยังอยู่ในไดเร็กทอรีเก่า) ถ้าฉันเรียก process.cwd () มันบอกว่าฉันอยู่ในไดเร็กทอรีฉันควรจะเป็น แต่ของฉัน เทอร์มินัลถ้าฉันโทรไปที่ pwd บอกว่าฉันอยู่ในสิ่งอื่น เพราะมันคนละกระบวนการ?
Jonovono

10
วิธีนี้เปลี่ยนไดเร็กทอรีการทำงานปัจจุบันของกระบวนการไม่ใช่เชลล์ เท่าที่ฉันรู้การเปลี่ยน cwd ภายนอกของกระบวนการทำงานนั้นค่อนข้างซับซ้อนและไม่แนะนำ อะไรคือเหตุผลที่คุณต้องการทำสิ่งนี้?
hexacyanide

3
อืม. โอเคขอบคุณ. เหตุผลที่ฉันต้องการทำเช่นนี้เพราะฉันกำลังสร้างแอปเทอร์มินัลสำหรับจัดระเบียบโครงการของฉัน โดยพื้นฐานแล้วฉันต้องการที่จะสามารถแสดงรายการโครงการของฉันและเปลี่ยนตำแหน่งเชลล์ปัจจุบันเป็นสิ่งนั้นได้อย่างง่ายดาย ตอนนี้ฉันคิดเกี่ยวกับเรื่องนี้ฉันจะดูว่า z ( github.com/rupa/z ) ทำสิ่งนี้อย่างไร แม้ว่าจะทำแบบทุบตีก็ตาม บางทีฉันอาจจะทำในแอปเปิ้ลสคริป?
Jonovono

@hexacyanide ขอบคุณสำหรับการเพิ่มที่รบกวนเพราะการเปลี่ยนแปลงไม่สอดคล้องกัน
Eugen Sunic

33

ไม่มีเมธอดในตัวสำหรับ Node เพื่อเปลี่ยน CWD ของเชลล์ที่อยู่เบื้องหลังที่รันกระบวนการโหนด

คุณสามารถเปลี่ยนไดเรกทอรีการทำงานปัจจุบันของกระบวนการ Nodeprocess.chdir()ผ่านคำสั่ง

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

เมื่อมีกระบวนการ Node คุณจะพบว่าตัวเองกลับมาอยู่ใน CWD ที่คุณเริ่มต้นกระบวนการ


14

สิ่งที่คุณพยายามทำนั้นไม่มีทางเป็นไปได้ เหตุผลก็คือในระบบ POSIX (Linux, OSX ฯลฯ ) กระบวนการลูกไม่สามารถแก้ไขสภาพแวดล้อมของกระบวนการหลักได้ ซึ่งรวมถึงการแก้ไขไดเร็กทอรีการทำงานของกระบวนการพาเรนต์และตัวแปรสภาพแวดล้อม

เมื่อคุณอยู่ใน commandline และคุณจะไปดำเนินการ Node สคริปต์ของคุณกระบวนการปัจจุบันของคุณ ( bash, zshสิ่ง) spawns กระบวนการใหม่ที่มีมันเป็นสภาพแวดล้อมที่ตัวเองมักจะสำเนาของสภาพแวดล้อมในปัจจุบันของคุณ (มันเป็นไปได้ที่จะเปลี่ยนผ่านระบบโทรศัพท์ ; แต่อยู่นอกเหนือขอบเขตของการตอบกลับนี้) ทำให้กระบวนการดังกล่าวสามารถทำสิ่งที่จำเป็นต้องทำด้วยการแยกอย่างสมบูรณ์ เมื่อกระบวนการย่อยออกการควบคุมจะถูกส่งกลับไปยังกระบวนการของเชลล์โดยที่สภาพแวดล้อมไม่ได้รับผลกระทบ

มีสาเหตุหลายประการสำหรับสิ่งนี้ แต่สำหรับหนึ่งลองนึกดูว่าคุณเรียกใช้สคริปต์ในพื้นหลัง (ผ่าน./foo.js &) และในขณะที่ทำงานสคริปต์ก็เริ่มเปลี่ยนไดเร็กทอรีการทำงานของคุณหรือแทนที่PATHไฟล์. นั่นคงเป็นฝันร้าย

หากคุณจำเป็นต้องดำเนินการบางอย่างที่ต้องเปลี่ยนไดเร็กทอรีการทำงานของเชลล์คุณจะต้องเขียนฟังก์ชันในเชลล์ของคุณ ตัวอย่างเช่นหากคุณใช้ Bash คุณสามารถใส่สิ่งนี้ไว้ใน~/.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

หากคุณต้องการทำสิ่งที่ซับซ้อนมากขึ้นนอกจากนี้คุณสามารถเรียกใช้สคริปต์ nodejs จากฟังก์ชันนั้นได้ตลอดเวลา

นี่เป็นวิธีเดียวที่คุณจะทำได้ในสิ่งที่คุณพยายามทำ


10

คำตอบสั้น ๆ : ไม่ (ง่าย?) แต่คุณสามารถทำสิ่งที่ตอบสนองวัตถุประสงค์ของคุณได้

ฉันได้ทำเครื่องมือที่คล้ายกัน (คำสั่งเล็ก ๆ ที่ให้คำอธิบายของโปรเจ็กต์ตั้งค่าสภาพแวดล้อมเส้นทางไดเร็กทอรี ฯลฯ ) สิ่งที่ฉันทำคือตั้งค่าทุกอย่างแล้ววางไข่ด้วย:

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

หลังจากดำเนินการคุณจะอยู่ในเชลล์ที่มีไดเร็กทอรีใหม่ (และในกรณีของฉันคือสภาพแวดล้อม) แน่นอนคุณสามารถเปลี่ยน bash สำหรับเปลือกที่คุณต้องการ ความแตกต่างที่สำคัญกับสิ่งที่คุณขอในตอนแรกคือ:

  • มีกระบวนการเพิ่มเติมดังนั้น ...
  • คุณต้องเขียน 'exit' เพื่อกลับมาแล้ว ...
  • หลังจากที่มีอยู่แล้วการเปลี่ยนแปลงทั้งหมดจะถูกยกเลิก

อย่างไรก็ตามสำหรับฉันแล้วความแตกต่างนั้นเป็นสิ่งที่พึงปรารถนา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.