กำหนดไดเร็กทอรีการทำงานของบรรทัดรับคำสั่งเมื่อรันสคริปต์ node bin


121

ฉันกำลังสร้างส่วนต่อประสานบรรทัดคำสั่งของโหนด มีการติดตั้งทั่วโลกและใช้ไฟล์ bin เพื่อดำเนินการ

ฉันวางแผนที่จะเปิดหน้าต่างคำสั่งที่ไดเร็กทอรีรูทของไฟล์ที่ฉันกำลังทำงานจากนั้นเพียงแค่รันคำสั่ง แต่ฉันไม่สามารถกำหนดไดเร็กทอรีการทำงานปัจจุบันได้เนื่องจากprocess.cwd()กำลังส่งคืนไดเร็กทอรีของโหนดแพ็กเกจ ในตอนแรกฉันสันนิษฐานว่าเนื่องจากโค้ดถูกเรียกใช้โดยใช้ไฟล์แบตช์เป็นตัวห่อ (นั่นคือวิธีที่ไฟล์ bin สามารถดำเนินการโดยไม่มีโหนดที่จุดเริ่มต้น) จึงเป็นไปไม่ได้ แต่ coffee-script สามารถจัดการได้ ฉันดูแหล่งที่มาของสคริปต์กาแฟ แต่ไม่สามารถติดตามได้ (มีประสบการณ์ไม่เพียงพอ)

หากต้องการทดสอบด้วยตัวคุณเองให้สร้างแพ็คเกจด้วยไฟล์ package.json นี้:

{
  "name": "test-package",
  "version": "1.0.0",
  "bin": {
    "test-package":  "./bin/test-package"
  },
  "main": "/lib/test"
}

ไฟล์แพ็กเกจทดสอบนี้ใน bin:

#!/usr/bin/env node

var path = require('path');
var fs   = require('fs');
var lib  = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');

require(lib + '/test');

ใครช่วยให้ความกระจ่างเกี่ยวกับเรื่องนี้

จากนั้นลองรับไดเร็กทอรีบรรทัดคำสั่งภายใน lib / test

คำตอบ:


196
  • process.cwd() ส่งคืนไดเร็กทอรีที่มีการเรียกใช้คำสั่ง (ไม่ใช่ไดเร็กทอรีของโหนดแพ็กเกจ) หากไม่ได้รับการเปลี่ยนแปลงโดย 'process.chdir' ภายในแอปพลิเคชัน
  • __filename ส่งคืนพา ธ สัมบูรณ์ไปยังไฟล์ที่วางไว้
  • __dirname__filenameส่งกลับเส้นทางสัมบูรณ์ไปยังไดเรกทอรีของ

หากคุณต้องการโหลดไฟล์จากไดเร็กทอรีโมดูลของคุณคุณต้องใช้พา ธ สัมพัทธ์

require('../lib/test');

แทน

var lib  = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');

require(lib + '/test');

มันสัมพันธ์กับไฟล์ที่เรียกมาจากเสมอและไม่ขึ้นอยู่กับผู้อำนวยการงานปัจจุบัน


2
หลังจากprocess.chdir()นี้มีวิธีใดบ้างที่จะได้รับต้นฉบับ?
reergymerej

@reergymerej คุณอาจต้องการจัดเก็บ cwd ก่อนที่จะดำเนินการ chdir () (เช่นvar originalCwd = process.cwd();จากนั้นดำเนินการของคุณprocess.chdir()และคุณสามารถกลับไปที่ต้นฉบับได้ในภายหลัง)
หมุน

เป็น../lib/testแบบพกพา?
Sebastian

ไม่ไม่ใช่โซลูชันแบบพกพาเนื่องจาก windows ใช้แบ็กสแลช ดังนั้นหากคุณพยายามเรียกใช้ใน windows มันจะไม่ทำงาน
zachdyer

1
จริงๆแล้วสำหรับ NodeJS นี้เหมือนกันทั้งหมด แม้แต่บน Windows คุณก็สามารถต้องการพา ธ สัมพัทธ์ในแบบ Unix ได้อย่างสะดวก จึง../lib/testพกพาได้ในขณะที่คู่ของ Windows ..\lib\testไม่ใช่ ...
Christian Ulbrich

48

ไดเรกทอรีการทำงานปัจจุบัน

ในการรับไดเร็กทอรีการทำงานปัจจุบันคุณสามารถใช้:

process.cwd()

อย่างไรก็ตามโปรดทราบว่าสคริปต์บางตัวที่สะดุดตาจะเปลี่ยนไดเร็กทอรีการทำงานปัจจุบันด้วยprocess.chdir().

เส้นทางโมดูลโหนด

คุณสามารถรับเส้นทางของโมดูลปัจจุบันด้วย:

  • __filename
  • __dirname

ไดเร็กทอรีดั้งเดิม (ที่ซึ่งคำสั่งเริ่มต้น)

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

process.env.INIT_CWD

ไดเร็กทอรีดั้งเดิมเมื่อทำงานกับสคริปต์ NPM

บางครั้งก็เป็นที่พึงปรารถนาที่จะเรียกใช้สคริปต์ NPM ในไดเร็กทอรีปัจจุบันไม่ใช่รูทของโปรเจ็กต์

ตัวแปรนี้มีอยู่ในสคริปต์แพ็กเกจ npm เป็น:

$INIT_CWD.

คุณต้องใช้ NPM เวอร์ชันล่าสุด หากไม่มีตัวแปรนี้ตรวจสอบให้แน่ใจว่า NPM เป็นปัจจุบัน

สิ่งนี้จะช่วยให้คุณเข้าถึงเส้นทางปัจจุบันใน package.json ของคุณเช่น:

scripts: {
  "customScript": "gulp customScript --path $INIT_CWD"
}

process.env.INIT_CWDส่งคืนผบ.package.json
วอห์น

2
ระวัง $ INIT_CWD ใช้งานได้กับ Linux เท่านั้น สำหรับ Windows คุณจะต้องใช้% INIT_CWD% ฉันคิดว่าปัญหานี้สามารถเอาชนะได้โดยใช้npmjs.com/package/cross-envแต่ฉันยังไม่ได้ลองด้วยตัวเอง
Stephanie

3

หรือหากคุณต้องการรับไดเร็กทอรีปัจจุบันของสคริปต์ NodeJS ปัจจุบันเพียงอย่างเดียวคุณสามารถลองสิ่งง่ายๆเช่นนี้ โปรดทราบว่าสิ่งนี้จะไม่ทำงานใน Node CLI เอง:

var fs = require('fs'),
    path = require('path');

var dirString = path.dirname(fs.realpathSync(__filename));

// output example: "/Users/jb/workspace/abtest"
console.log('directory to start walking...', dirString);

3

path.resolve('.')require('path')ยังเป็นตัวเลือกที่น่าเชื่อถือและสะอาดเพราะเราเกือบตลอดเวลา มันจะให้เส้นทางที่แน่นอนของไดเร็กทอรีจากตำแหน่งที่เรียก


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