2

给定以下脚本:

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\" --whatIfl:\my folder\Files - Some Files In Here\

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

我注意到,如果我删除尾部斜杠,它将起作用。但是,这仍然表明节点脚本没有正确处理输入,因为单引号引起的字符串不应该这样做。

有没有办法使这项工作?

4

1 回答 1

4

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

通常, Windows 上的 PowerShell 必须在幕后执行重新引用,以确保仅使用 -quoting,因为在解析命令行时"..."不能假定外部程序也理解-quoting(在 Windows 上每个程序'...'必须自己做)。

Windows PowerShell在以空格结尾\ 嵌入空格的参数方面糟糕,不正确地重新引用它们;例如:

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

在幕后被翻译成如下命令行:

foo.exe "c:\ foo \" bar

这是被破坏的,因为大多数应用程序(包括 PowerShell自己的 CLI)都明智地假设\"是一个转义 "字符。逐字逐句,认为论点继续, bar然后隐含地结束,尽管形式上没有结束"

PowerShell [Core] v6+ 更明智地将上面的内容转换为foo.exe "c:\foo \\" bar,其中\\被解释为转义的\,而下面的内容"再次具有语法功能。


如果您被困在Windows PowerShell中,您唯一的选择是:

  • 要么:如果可能,请不要尾随\
  • 否则:手动将其加倍( \\),但仅当参数还包含空格时才这样做(否则,\\将按原样保留,尽管在文件系统路径通常是良性的情况下)。
于 2020-01-29T03:42:20.397 回答