我在Windows上的git bash中使用以下git命令:
git log --format="%C(cyan)%cd%Creset %s" --date=short -5
它显示提交日期(%cd
),然后显示提交消息(%s
)。提交日期用颜色标记包裹:%C(cyan)
开始彩色输出和%Creset
停止彩色输出。
虽然它在git
bash中可以正常工作,但不能很好地使用cmd
:%cd%
Windows外壳程序将其扩展到当前工作目录($PWD
在bash中等效)。
因此,当通过运行该命令时cmd
,我在第一栏中看到当前的工作目录,而不是提交日期! git bash:
2015-10-08 commit msg
2015-10-08 commit msg
2015-10-07 commit msg
2015-10-06 commit msg
2015-10-06 commit msg
命令:
D:\git\someFolderCreset commit msg
D:\git\someFolderCreset commit msg
D:\git\someFolderCreset commit msg
D:\git\someFolderCreset commit msg
D:\git\someFolderCreset commit msg
实际上,我从不cmd
直接使用自己,而是在编写具有以下内容的nodejs(0.12)脚本时发现了此行为:
require('child_process').execSync('git log --format=...', {stdio: 'inherit'})
cmd
在Windows上使用when 由节点执行。
一个简单的解决方法可能是引入一个空间以防止%cd%
被发现,即更改
git log --format="%C(cyan)%cd%Creset %s" --date=short -5
至
git log --format="%C(cyan)%cd %Creset%s" --date=short -5
但是,这引入了一个冗余空间(我之前删除了另一个空间,%s
但这仍然是一个hack,需要手动干预)。
有没有办法防止Windows Shell扩展?
我发现了有关使用%%
或^%
转义的信息,%
但此处不是解决方案:
# produces superfluous ^ characters
git log --format="%C(cyan)^%cd^%Creset %s" --date=short -5
^2015-10-08^ commit msg
^2015-10-08^ commit msg
^2015-10-07^ commit msg
^2015-10-06^ commit msg
^2015-10-06^ commit msg
# seems the expansion is done at command parse time
git log --format="%C(cyan)%%cd%%Creset %s" --date=short -5
%D:\git\someFolder commit msg
%D:\git\someFolder commit msg
%D:\git\someFolder commit msg
%D:\git\someFolder commit msg
%D:\git\someFolder commit msg
理想的解决方案应该是与bash和cmd兼容,而不产生多余的字符,或者是javascript中的转义函数,以转义Windows的通用UNIX-
y命令以防止扩展(如果可以创建这种转义函数)。
如果你真的 需要 得到 壳 参与(这是不可能的,因为你的国家,你想要的命令与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 -5
var 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本身负责在将双引号传递给目标程序之前删除双引号。
$
它们会对-prefixed令牌执行可能不需要的扩展(此处不存在问题);但是,为了保持Windows兼容,您 必须 使用双引号。从技术上讲,将此技术应用于双引号字符串会将其分成一系列双引号 子字符串,这些子字符串 散布在 未加引号的
%
实例中。类似于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]
。
我想读取Dockerfile中的变量,该变量在文件中定义。有什么办法可以做到这一点吗? 这是我的DockerFile:
在Dart(2.15.0)中,我试图通过定义toJson方法将jsonEncode与枚举一起使用。它不起作用。 根据文档,将查找方法。 当直接在枚举上调用时,扩展可以工作,但是不知何故jsonEncode没有找到toJSON。 Dart如何获取枚举的“值”https://dart.dev/guides/language/extension-methods 知道这是一个错误还是预期的行为吗? 否则,
问题内容: 假设我有以下情况: 有没有一种方法可以保证实现的任何类也必须扩展?我不想创建一个抽象类,因为我希望能够以类似的方式混合其他一些接口。 例如: 问题答案: Java接口无法扩展类,这很有意义,因为类包含无法在接口内指定的实现细节。 解决此问题的正确方法是通过将接口也完全从实现中分离出来。所述等可以扩展接口以迫使程序员来实现相应的方法。如果要在所有实例之间共享代码,则可以将(可能是抽象的)
我有一个非常简单的练习,我注册客户端名称(字符串),我使用数组来做到这一点,所以当我添加一个新的我将使用另一个辅助数组,然后增加原来的长度,或者我将使用System.array复制,有没有其他方法,逐渐增加数组长度,因为你需要添加元素到该数组,不涉及辅助数组?
我正在做一个Jenkins的工作,它接受来自用户的一些参数。我遇到了一个不希望的行为:在我的脚本有机会读取环境变量之前,Jenkins似乎在参数环境变量中扩展了环境变量引用。 如果用户输入 作为参数,我的脚本实际看到的是 的内容;环境变量已展开。如果输入的值包含 我的脚本只能看到一个 。但是,如果它包含环境中不存在,则该值将保持不变(不会引发任何类型的错误)。 这很不方便,因为它甚至出现在密码字段
问题内容: 我想将背景URL存储在自定义属性(CSS变量)中,并将其与background属性一起使用。但是,当使用字符串作为参数时,我找不到插值的方法。 这是我的示例代码: 我知道可以使用插值函数在Sass或LESS中轻松完成此操作,但我很好奇是否有一种无需任何预处理器的方法。 问题答案: 您可以使用大多数CSS函数执行插值,包括的示例。实际上,插值是自定义属性的主要功能之一。 但是,您不能使用