簡體   English   中英

如何在 nodejs 中解析包含環境變量的路徑?

[英]How to resolve a path that includes an environment variable, in nodejs?

我想運行一個可執行文件並且它的路徑包含一個環境變量,例如如果我想運行 chrome.exe 我想寫這樣的東西

var spawn = require('child_process').spawn;
spawn('chrome',[], {cwd: '%LOCALAPPDATA%\\Google\\Chrome\\Application', env: process.env})

代替

var spawn = require('child_process').spawn;
spawn('chrome',[], {cwd: 'C:\\Users\myuser\\AppData\\Local\\Google\\Chrome\\Application', env: process.env}).

我可以使用 package 來實現這一目標嗎?

您可以使用正則表達式將您的變量替換為process.env的相關屬性:

let str = '%LOCALAPPDATA%\\Google\\Chrome\\Application'
let replaced = str.replace(/%([^%]+)%/g, (_,n) => process.env[n])

當它是一個單行時,我不認為需要一個包。

我意識到這個問題要求 Windows 環境變量,但我修改了@Denys Séguret 的答案以處理 bash 的${MY_VAR}$MY_VAR樣式格式,因為我認為它可能對來到這里的其他人有用。

注意:兩個 arguments 是因為有兩個基於格式變化的分組。

str.replace(/\$([A-Z_]+[A-Z0-9_]*)|\${([A-Z0-9_]*)}/ig, (_, a, b) => process.env[a || b])

在DenysSéguret的優秀答案中添加了TypeScript友好的補充:

let replaced = str.replace(/%([^%]+)%/g, (original, matched) => {
      const r = Process.env[matched]
      return r ? r : ''
})

在Linux / MacOS上,我產生了一個用env變量解析路徑的進程,是安全的 - 讓bash為你做的工作。 顯然性能較差,但更強大。 看起來像這樣:

import * as cp from 'child_process';

// mapPaths takes an array of paths/strings with env vars, and expands each one

export const mapPaths = (searchRoots: Array<string>, cb: Function) => {

  const mappedRoots = searchRoots.map(function (v) {
    return `echo "${v}"`;
  });

  const k = cp.spawn('bash');

  k.stdin.end(mappedRoots.join(';'));
  const results: Array<string> = [];
  k.stderr.pipe(process.stderr);

  k.stdout.on('data', (d: string) => {
    results.push(d);
  });

  k.once('error',  (e) => {
    log.error(e.stack || e);
    cb(e);
  });

  k.once('exit', code => {

    const pths = results.map((d) => {
      return String(d || '').trim();
    })
    .filter(Boolean);

    cb(code, pths);

  });
};

這是一個通用的輔助函數:

/**
 * Replaces all environment variables with their actual value.
 * Keeps intact non-environment variables using '%'
 * @param  {string} filePath The input file path with percents
 * @return {string}          The resolved file path
 */
function resolveWindowsEnvironmentVariables (filePath) {
  if (!filePath || typeof(filePath) !== 'string') {
    return '';
  }

  /**
   * @param  {string} withPercents    '%USERNAME%'
   * @param  {string} withoutPercents 'USERNAME'
   * @return {string}
   */
  function replaceEnvironmentVariable (withPercents, withoutPercents) {
    let found = process.env[withoutPercents];
    // 'C:\Users\%USERNAME%\Desktop\%asdf%' => 'C:\Users\bob\Desktop\%asdf%'
    return found || withPercents;
  }

  // 'C:\Users\%USERNAME%\Desktop\%PROCESSOR_ARCHITECTURE%' => 'C:\Users\bob\Desktop\AMD64'
  filePath = filePath.replace(/%([^%]+)%/g, replaceEnvironmentVariable);

  return filePath;
}
  • 可以從任何地方調用
  • 首先進行基本類型檢查,您可能希望更改第一個if塊中默認返回的內容
  • 功能以解釋其功能的方式命名
  • 變量的命名方式可以解釋它們是什么
  • 添加的評論清楚地說明了可能發生的結果
  • 處理以百分比形式包裝的非環境變量,因為Windows文件系統允許將文件夾命名為%asdf%
  • JSDoc在某些編輯器中阻止自動文檔,類型檢查和自動完成
  • 您可能還想根據需要使用if (process.platform !== 'win32') {}

這些答案很瘋狂。 就可以使用path

const folder = require('path').join(
    process.env.LOCALAPPDATA,
    'Google/Chrome/Application',
);

console.log(folder); // C:\Users\MyName\AppData\Local\Google\Chrome\Application

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM