如果你真的 需要 得到 壳 参与(这是不可能的,因为你的国家,你想要的命令与Windows的工作都
cmd.exe和
bash)的,立即考虑下面的解决方案; 有关 绕过 该问题 的无 壳 替代方案 __,请参阅 底部 的解决方案。
在帽子的提示MC ND为提高我原来通过建议配售双引号的方法
%的实例,而不是潜在的变量名 之间
%的实例和建议澄清重
execFileSync。
“转义” %
字符。对于cmd.exe
如MC
ND的回答所述,您从技术上讲不能
%在Windows命令提示符下转义(可以使用批处理文件
%%,但是从其他环境(如Node.js)调用Shell命令时,此操作无效,并且通常无法跨平台)。
但是, 解决方法 是 在每个%
实例周围加上 双引号 :
// Input shell command.var shellCmd = 'git log --format="%C(cyan)%cd%Creset %s" --date=short -5'// Place a double-quote on either end of each '%'// This yields (not pretty, but it works):// git log --format=""%"C(cyan)"%"cd"%"Creset "%"s" --date=short -5var escapedShellCmd = shellCmd.replace(/%/g, '"%"')// Should work on both Windows and Unix-like platforms:console.log(require('child_process').execSync(escapedShellCmd).toString())插入的双引号会阻止
cmd.exe识别诸如
%cd%变量引用之类的标记(
"%"cd"%"不会扩展)。
之所以有效,是因为在由目标程序处理时,多余的双引号最终会从字符串中删除:
Windows :(
git.exe
大概通过C运行时)然后负责从组合字符串中删除多余的双引号。类似于Unix(类似于 POSIX的shell,例如Bash):shell本身负责在将双引号传递给目标程序之前删除双引号。
- 警告 :通常在命令中使用 双引号 意味着您需要注意类似POSIX的shell,
$
它们会对-prefixed令牌执行可能不需要的扩展(此处不存在问题);但是,为了保持Windows兼容,您 必须 使用双引号。
- 警告 :通常在命令中使用 双引号 意味着您需要注意类似POSIX的shell,
从技术上讲,将此技术应用于双引号字符串会将其分成一系列双引号 子字符串,这些子字符串 散布在 未加引号的
%实例中。类似于POSIX的shell仍将其识别为 单个 字符串-子字符串被双引号引起来并且直接与
%实例邻接。(如果将这种技术应用于
未加引号的
字符串,则逻辑是相反的:实际上是在双引号
%实例中进行拼接。)然后,将子字符串周围的双引号(被视为语法元素而不是字符串的一部分)当子字符串连接在一起以形成单个文字以传递给目标程序时,将其删除。
通过完全避免使用壳来绕过该问题
注意 :以下版本基于
execFile[Sync],仅在 调用 外部可执行文件
时才有效(在OP的情况下是这样:
git.exe)-相比之下,对于调用 shell内置文件 (内部命令)或Windows 批处理文件
,您无法避免
exec[Sync],因此无法通过
cmd.exe(在视窗)。[1]
如果您
使用execFileSync
而不是
execSync,
则不会涉及 外壳程序(
cmd.exe在Windows上),因此您 不必担心转义
%字符。或任何其他外壳元字符,为此:
require('child_process').execFileSync('git', [ 'log', '--format=%C(cyan)%cd%Creset %s', '--date=short', '-5' ], {stdio: 'inherit'})注意如何的参数,必须提供 单独 作为一个元素 阵列 ,并且 没有嵌入引用 。
[1]在Windows上,不能直接使用调用脚本文件(例如Python脚本)
execFile[Sync],而是可以将解释器可执行文件(例如
python)作为要执行的文件,而将脚本文件作为参数。在类似Unix的平台上,您
可以
直接调用脚本,只要它们具有shebang行并标记为可执行文件即可。
execFile[Sync]可以 用来调用Windows 批处理文件 ,但
cmd.exe总是像一样插值参数
exec[Sync]。



