Argument escaping not interpreted correctly when running node.js script from Windows PowerShell

对着背影说爱祢 提交于 2020-03-15 05:50:49

问题


Given the following script:

const yargs = require('yargs');

const argv =
    yargs
        .usage('Usage: $0 [--whatIf]')
        .alias('d', 'directory')
        .alias('wi', 'whatIf')
        .nargs('d', 1)
        .describe('d', 'alphabetize this directory')
        .describe('whatIf', 'show what would happen if run')
        .demandOption(['d'])
        .argv;

console.log(argv.directory);

If I invoke the script from Windows PowerShell like so: node .\alphabetizer.js -d 'l:\my folder\Files - Some Files In Here\' --whatIf I get the output l:\my folder\Files - Some Files In Here\" --whatIf where I would expect just l:\my folder\Files - Some Files In Here\. It works OK with folder names that require no escaping, but it seems to get confused by the escaping.

If I examine process.argv, I can see the same escaping issue.

I have noticed that if I remove the trailing slash it will work. However, this still points to the node script not handling the input properly, because this should not be necessary with string set off by single quotes.

Is there a way to make this work?


回答1:


Both Windows PowerShell (powershell.exe) and PowerShell [Core] v6+ (pwsh) are fundamentally broken with respect to quoting arguments for external programs properly - see this answer for background info.

Generally, PowerShell on Windows has to perform re-quoting behind the scenes in order to ensure that just "..."-quoting is used, given that external programs can't be assumed to understand '...'-quoting too when parsing their command line (which on Windows every program has to do itself).

Windows PowerShell is more broken with respect to arguments that end in \ and have embedded spaces, re-quoting them improperly; e.g.:

PS> foo.exe 'c:\foo \' bar

is translated into the following command line behind the scenes:

foo.exe "c:\ foo \" bar

This is broken, in that most applications - including PowerShell's own CLI - sensibly assume that the \" is an escaped " char. to be taken verbatim, thinking that the argument continues with  bar and then implicitly ends, despite the formal lack of a closing ".

PowerShell [Core] v6+ more sensibly translates the above to foo.exe "c:\foo \\" bar, where the \\ is interpreted as an escaped \, and the following " again has syntactic function.


If you're stuck with Windows PowerShell, your only choices are:

  • either: if possible, leave off the trailing \
  • otherwise: manually double it (\\), but only do so if the argument also contains spaces (otherwise, the \\ will be retained as-is, though in the case of filesystem paths that is usually benign).


来源:https://stackoverflow.com/questions/59959790/argument-escaping-not-interpreted-correctly-when-running-node-js-script-from-win

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!