从Windows PowerShell运行node.js脚本时无法正确解释参数转义 [英] Argument escaping not interpreted correctly when running node.js script from Windows PowerShell

查看:296
本文介绍了从Windows PowerShell运行node.js脚本时无法正确解释参数转义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下脚本:

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);

如果像这样从Windows PowerShell调用脚本:node .\alphabetizer.js -d 'l:\my folder\Files - Some Files In Here\' --whatIf我得到的输出是l:\my folder\Files - Some Files In Here\" --whatIf,而我只希望它是l:\my folder\Files - Some Files In Here\.对于不需要转义的文件夹名称,它可以正常工作,但是转义似乎使它感到困惑.

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.

如果我检查process.argv,我会看到相同的转义问题.

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?

推荐答案

在引用外部程序的参数方面,Windows PowerShell(powershell.exe)和PowerShell [Core] v6 +(pwsh)都从根本上被破坏了. 正确-请参阅此答案以获取背景信息.

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.

通常,Windows上的 PowerShell必须在后台执行重新引用 ,以确保仅使用"..."引用,因为外部程序可以解析命令行时(在Windows上每个程序都必须自己执行),也不应该理解'...'-引号.

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损坏了 more ,不正确地重新报价;例如:

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

这是,在大多数应用程序中-包括PowerShell的转义的 "字符.被认为是 verbatim ,以为尽管正式缺少",但该论点以 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 +更明智地将以上内容翻译为foo.exe "c:\foo \\" bar,其中\\被解释为转义的\,而随后的"再次具有语法功能.

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.

如果您坚持使用 Windows PowerShell ,则唯一的选择是:

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).

这篇关于从Windows PowerShell运行node.js脚本时无法正确解释参数转义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆