如何在命令行中可靠地使用“rem”而不忽略相邻命令?

     2023-02-21     178

关键词:

【中文标题】如何在命令行中可靠地使用“rem”而不忽略相邻命令?【英文标题】:How to reliably use `rem` within a command line without ignoring adjacent commands? 【发布时间】:2016-04-19 05:43:36 【问题描述】:

我正在尝试使用rem 命令在包含多个命令的命令行中添加注释。这里有一些例子来说明我的意思:

echo Hello & rem.Comment & echo world!

(echo Hello & rem.Comment) & echo world!

这工作得很好,每行中的两个echo 命令都按我的预期执行。 . 似乎修改了 rem 命令的行为,使其不会将剩余的行视为注释:

Hello 
world!

如果我放置了 SPACE(或任何其他分隔符 TAB,;=)而不是 .,则剩下的行,因此第二个echo 将被忽略(对于第二个示例,出现More? 提示,因为) 是注释的一部分,而cmd 期望关闭),因为() :

Hello 

我发现除了.,以下字符也可以使用::/\[]+。 其他工作是转义分隔符:^SPACE^TAB^,^;^=

不过,是否有安全可靠的方法来做到这一点?

我会很高兴有一个适用于命令提示符和批处理文件的解决方案。


根据this external reference,熟悉的语法echo.在某些情况下返回空行会失败,因此建议使用echo(,因为这是唯一可靠的方法。

但是,对于rem( 不起作用,rem( 之后的所有内容都不会被识别为命令。


由于我知道 Windows XP 中 rem 命令的一个奇怪错误(参考 this external link: rem %~),我对适用于 Windows Vista、Windows 7 或更高版本的解决方案感兴趣.

【问题讨论】:

从程序设计的角度来看,为什么要将内联注释放在代码中间而不是两端? @SomethingDark - 为什么不呢?内联注释可能很有用。 我通常使用 cmets 来解释代码的作用。在我写完我要评论的那一行之前这样做似乎很奇怪。 @SomethingDark - 但如果一行由连接的命令组成,这可能是完全合理的, 我删除了关于 rem %~ 问题的错误声明,因为它仅限于 Windows XP;所以对于rem 命令,cmd 可能没有更改... 【参考方案1】:

“奇怪”REM %~“错误”不仅限于 XP。它存在于使用 CMD.EXE 的所有现代版本的 Windows 中。阅读您的问题后,我wrote Simon of SS64 a note 澄清了这个问题。如果变量 var 存在并且你有 rem %var:=,则 REM 也会失败。

所以从技术上讲,盲目使用 REM 并不能保证安全。

但是,如果您愿意接受致命的 % 扩展风险,那么您列出的大多数 hack 都可以安全使用,但如果该行包含至少一个通过 & 的附加命令或&&.

如果存在名为REM(无扩展名)的文件,则在任何情况下都不能安全使用REM.

如果当前文件夹包含名为test.bat 的文件并且您使用REM\..\test.bat,则文件夹分隔符\/ 总是失败。

以类似的方式,REM:\..\test.bat 总是失败。

在类似的情况下,其他每一个 hack 都可能单独失败。例如,REM^[tab]\..\test.bat 单独失败,但如果与另一个命令连接则可以工作。这是我发现的唯一一种+[]^[tab] 可能失败的情况。

还有其他一些黑客可能会失败的情况。

如果 remC.bat 存在,则文件名中有效的集合 C(^[space]^,^;^=)中的任何字符都可能单独失败。例如,以下独立失败:

rem^  Fails if "rem .bat" exists

然而,当与另一个命令连接时,它们都是安全的:

echo OK&rem^  This is safe
rem^  This is safe &echo OK

临时更新

上面有些是错误的。正在http://www.dostips.com/forum/viewtopic.php?f=3&t=6895&p=44813#p44813 进行调查。

我相信以下是保证在所有情况下都能正常工作的最简单形式(忽略无效的 % 扩展)

REM: At least one space (or other token delimiter) must be after :
REM\ At least one space (or other token delimiter) must be after \
REM/ At least one space (or other token delimiter) must be after /
REM^[tab] At lease one space (or other token delimiter) must be after [tab]

但在尘埃落定之前,我不会更正之前的信息

结束临时更新


我最喜欢使用内联 cmets 的方法是使用不可能的变量。只有动态伪变量可以在名称中包含=,并且任何变量名称都不能包含两个=。所以我喜欢使用%= Remark goes here =%。这种形式的美妙之处在于它几乎可以在任何地方使用而不受惩罚,只要评论不包含%:。它甚至可以在带括号的代码块中安全使用。

for %%F in (*) do (
   %= Comment within code block     =%
   %= 2nd comment within code block =%
   FINDSTR /B %=Must match beginning of line=%  "string" %= Search string =%  "%%F" %= File to search =%
)

【讨论】:

编辑 - 对失败情况进行了重大更正 谢谢! %= =% 语法非常酷,但显然只适用于批处理文件;我正在为cmd 和批处理寻找“包罗万象”的解决方案,所以rem 似乎是唯一的方法...... @aschipfl - 我在 Win 10 上的测试显示,在独立使用时(没有 &),所有变体都可能失败。但是对于某些人来说,jeb 在 Win 7 上没有发现任何故障,我在工作时在我的 Win 7 上证实了他的发现。今晚回家后,我会仔细检查我的 Win 10 调查结果。 我很惊讶rem^<TAB> Comment 有效,但我无法将 放入文件名(但我很确定有一种方法,你也在 dostips 上提到过) ;无论如何,是否有指向cmd(文件/目录。名称完成)的/F选项的链接,默认情况下该选项为ON?【参考方案2】:

REM 的这种变体似乎是在评论部分启用& 符号的安全方法。

REM/
REM\
REM:

尽管有@dbenham 的评论,但我无法创建任何会与这些 REM 变体发生冲突的文件(我尝试了REM.batREM;.bat 等等)。 在REM^<char> 之后添加一个空格总是一个好主意。

%~ 的问题无法解决,因为 cmd.exe 对每一行使用多个解析器阶段。 并且%~ 错误是在早期阶段(百分比扩展阶段)检测到的,就在将检测到REM 的阶段之前。

但是,我更喜欢内联 cmets 的百分比 cmets,由 dbenham 描述

编辑: 我从REM^<char> 中删除了插入符号,因为这无关紧要。

通常REM 注释该行的其余部分,因为批处理解析器在解析器的第 2 阶段检测到 REM 关键字并切换到仅用于 REM 的专用解析器。

但是当一个字符被附加到REM时,关键字将不会在阶段2中被检测到。 如果字符是\/;,=+( 之一,解析器稍后将删除它并执行正常 REM 命令。

这就是为什么在这种情况下可以识别命令运算符&&&||| 的原因。

为什么rem/ | break 失败,但(REM/) | break 有效? 这是因为管道启动了两个单独的 cmd 子进程。 带括号的命令将在子进程中第一次解析。 但是没有括号,父进程已经解析了REM/并检查文件是否存在(但不执行)。 但是当这样的文件存在时,解析器足够聪明,可以删除分隔符并检测到REM 是一个内部命令。 这种行为看起来有点奇怪。

【讨论】:

所有黑客都容易受到\..\x.bat 技巧的影响。请参阅我修改后的答案。 再一次,你是对的,但我只是忘了提到你应该总是在REM^<char> 部分后面添加一个空格。并且附加\..\..\..\windows\system32\calc.exe 似乎只是REM^` and REM ^ 的问题:` 当 REM 单独使用时,我不明白添加额外的空间如何避免 \..\x.bat 问题。 您编辑的答案实际上就是我在我的回答中所说的,但不是那么简洁。我同意大多数使用多个命令。但是 REM^\ 由于\..\x.bat 导致单机失败 @aschipfl 我编辑了我的答案,我希望它现在已经完成了

*忽略* C++和C#如何在命令行中显示百分比[重复]

】*忽略*C++和C#如何在命令行中显示百分比[重复]【英文标题】:*ignore*C++andC#Howtodisplaypercentageinacommandline[duplicate]【发布时间】:2013-10-0914:23:58【问题描述】:当我制作一个在命令行中显示进度的程序时,当进度增长时,如何制作... 查看详情

如何在命令行中从脚本运行函数?

】如何在命令行中从脚本运行函数?【英文标题】:HowcanIrunafunctionfromascriptincommandline?【发布时间】:2012-02-0717:46:55【问题描述】:我有一个脚本,它有一些功能。我可以直接从命令行运行其中一个函数吗?这样的?myScript.shfunc(... 查看详情

如何在命令行中使用选项创建 android 模拟器?

】如何在命令行中使用选项创建android模拟器?【英文标题】:howtocreateandroidemulatorincommandlinewithoptions?【发布时间】:2012-10-0212:36:40【问题描述】:我想用一些选项在命令行中创建模拟器,比如hw.mainKeys=false。我需要它是一个shell... 查看详情

如何使用 Python 3.x 在命令行中执行多个命令

】如何使用Python3.x在命令行中执行多个命令【英文标题】:HowtoexecutemultiplecommandincommandlinewithPython3.x【发布时间】:2021-04-2613:06:25【问题描述】:谢谢大家。我正在编写一个脚本来在命令行中执行多个命令。这是我整个剧本的一... 查看详情

如何在命令行中使用带有 gradle 的袜子来解决依赖关系?

】如何在命令行中使用带有gradle的袜子来解决依赖关系?【英文标题】:Howtousesockswithgradlefordependencyresolving,incommandline?【发布时间】:2016-04-1906:31:23【问题描述】:当没有代理服务器无法访问jcenter来解决依赖关系,并且我想使... 查看详情

如何在命令行中构建 C++ 文件

】如何在命令行中构建C++文件【英文标题】:howtobuildavc++fileincommandline【发布时间】:2009-04-0809:11:59【问题描述】:如何在命令行中构建一个用VC++开发的项目我不是VisualStudio(2003年或2005年或2008年)【问题讨论】:我不太明白你... 查看详情

如何使用命令行中的密码生成 openSSL 密钥?

】如何使用命令行中的密码生成openSSL密钥?【英文标题】:HowtogenerateanopenSSLkeyusingapassphrasefromthecommandline?【发布时间】:2011-05-1617:35:22【问题描述】:首先-如果我不提供密码会怎样?是否使用了某种伪随机短语?我只是在寻找... 查看详情

如何在命令行中运行 ZAP 扫描?

】如何在命令行中运行ZAP扫描?【英文标题】:HowtorunZAPscanincommandline?【发布时间】:2021-08-0311:59:24【问题描述】:我正在使用OWASPZAP工具在asp.net核心网络应用程序上运行笔测试。当我使用OwaspZAP的windows应用程序运行测试时,测... 查看详情

如何在命令行中输入? [复制]

】如何在命令行中输入?[复制]【英文标题】:HowdoIinputinacommandline?[duplicate]【发布时间】:2018-07-1515:45:49【问题描述】:我正在为一个班级做作业,并注意到我可能需要argc和argv,但是当我查找它以了解它时,我不断看到提到命... 查看详情

centos如何在命令行中使用ftp命令上传和下载文件

本文中,介绍在Linuxshell中如何使用ftp命令。包括如何连接FTP服务器,上传或下载文件以及创建文件夹。尽管现在有许多不错的FTP桌面应用,但是在服务器、SSH、远程会话中命令行ftp命令还是有很多应用的。比如。需要服务器从ft... 查看详情

如何在 Windows 的命令行中使用 MinGW 编译器?

】如何在Windows的命令行中使用MinGW编译器?【英文标题】:HowdoIusetheMinGWcompilerfromthecommandlineonWindows?【发布时间】:2013-11-1414:18:17【问题描述】:我已经在我的Windows7机器上安装了BloodshedDev-C++编译器。现在如何从命令行编译?【... 查看详情

如何在 Windows 命令行中使用参数运行 Python 脚本

】如何在Windows命令行中使用参数运行Python脚本【英文标题】:HowdoIrunPythonscriptusingargumentsinwindowscommandline【发布时间】:2013-07-0619:52:54【问题描述】:这是我的pythonhello.py脚本:defhello(a,b):print"helloandthat\'syoursum:"sum=a+bprintsumimportsys... 查看详情

在命令行中使用 maven 编译整个项目后如何运行单个类? [复制]

】在命令行中使用maven编译整个项目后如何运行单个类?[复制]【英文标题】:HowdoIrunasingleclassaftercompilingthewholeprojectwithmavenincommandline?[duplicate]【发布时间】:2018-03-2101:29:18【问题描述】:我可以在Eclipse中运行它,但是用命令行... 查看详情

如何从 Mac OS X 命令行或脚本可靠地响铃我的 iPhone?

】如何从MacOSX命令行或脚本可靠地响铃我的iPhone?【英文标题】:HowtoreliablyringmyiPhonefromMacOSXcommandlineorscript?【发布时间】:2016-03-1417:57:36【问题描述】:一家初创公司的网站必须在0/24运行。数据中心不会在中断时通知我们,即... 查看详情

如何在命令行中编译和链接项目?

】如何在命令行中编译和链接项目?【英文标题】:howtocompileandlinkprojectincommandline?【发布时间】:2016-11-0410:11:14【问题描述】:使用VisualStudio,我写了一个C++程序MyCat,所以它可以在VSIDE中编译生成一个MyCat.DLL文件。另外,我可... 查看详情

如何在命令行中使用 Visual Studio 编译 x64 代码?

】如何在命令行中使用VisualStudio编译x64代码?【英文标题】:Howtocompilex64codewithVisualStudioincommandline?【发布时间】:2011-02-0215:18:32【问题描述】:我想使用Windows命令行编译一个简单的hello-world风格的程序。clfile_name.c很简单。现在... 查看详情

如何在命令行中从 .NET 程序集中获取 IDL(或如何将 TLB 转换为 IDL)?

】如何在命令行中从.NET程序集中获取IDL(或如何将TLB转换为IDL)?【英文标题】:HowtogetIDLfroma.NETassembly(orhowtotoconvertTLBtoIDL)inacommandline?【发布时间】:2011-02-1900:34:11【问题描述】:我们有一个.NET程序集(实际上是Aspose.Words),... 查看详情

在 Windows 命令行中使用批处理文件中的参数

...发布时间】:2012-12-2612:35:39【问题描述】:在Windows中,如何访问批处理文件运行时传递的参数?例如,假设我有一个名为hello.bat的程序。当我在Windows命令行中输入hello-a时,如何让我的程序知道-a作为参数传入?【问题讨论】:... 查看详情