问题
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