我有一个Windows CMD脚本,它接受许多参数并执行EXE,首先传递一些硬编码参数,然后传递用户的所有参数.CMD脚本如下所示:
launcher.exe paramX paramY %*
Run Code Online (Sandbox Code Playgroud)
用户将从Windows shell执行CMD脚本,如下所示:
launcher.cmd param1 param2 param3 [...]
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果参数到CMD脚本包含壳等特殊字符< >和^,用户被迫通过前述各用3插入符号逸出这些^壳转义字符.
1)要将参数传递ten>one给EXE,用户必须按如下方式启动CMD:
launcher.cmd ten^^^>one
Run Code Online (Sandbox Code Playgroud)
这样做的原因是,shell特殊字符^,并>通过命令外壳在两个层面解释,首先在命令行和第二的CMD脚本中.因此,使用脱字符^外壳转义字符转义的shell必须应用两次.问题是这对用户来说并不明显,看起来很难看.
对于这个例子,一个更好的解决方案是用双引号括起参数.但是,这会分解为更复杂的示例,其中包含参数中的文字双引号.
2)要将参数传递"^给EXE,用户必须按如下方式启动CMD:
launcher.cmd "\"^^^^"
Run Code Online (Sandbox Code Playgroud)
在我的情况下,我想支持包含任何低ASCII字符序列的参数,不包括控制字符,即代码点0x20到0x7E.我知道会有一些例子,用户必须使用插入符号来逃避某些shell特殊字符.但是,我不希望用户在这些情况下每次都必须使用3个插入符,因为它们恰好是在调用CMD脚本而不是EXE.
我可以通过使用执行相同操作的EXE替换CMD脚本来解决此问题.但是,有没有办法改变CMD脚本,以便它将参数传递给EXE而不解释shell特殊字符?
我一直讨厌批处理,我仍然这样做,即使是最简单的事情,我更喜欢C或PHP/Perl.但这次我不能没有它,****叹气****.
我想将echo命令重定向到另一个命令.例如:
echo example | more
Run Code Online (Sandbox Code Playgroud)
但我也希望能够在管道的回声部分使用特殊字符:
echo & | more
Run Code Online (Sandbox Code Playgroud)
这当然没有用.所以我尝试过:
echo ^& | more
Run Code Online (Sandbox Code Playgroud)
哪个也没用.然后通过反复试验我发现:
echo ^^^& | more
Run Code Online (Sandbox Code Playgroud)
那很有效.但作为感兴趣的程序员我想知道为什么.为什么没有^&工作^^^&呢?
好的,我了解到可以使用&或&&将多个命令组合成一行,但似乎set实际上不能在同一行中进行插值的变量:
C:\Users\Andrew>set foo=hello, world!&& echo %foo%
%foo%
C:\Users\Andrew>echo %foo%
hello, world!
Run Code Online (Sandbox Code Playgroud)
为什么我不能做这项工作,有没有办法让它在一条线上工作?
我需要一个单行的原因是我正在使用的外部程序接受一个命令作为预运行钩子,当然,我需要运行多个命令.
" hello, world!应该用双引号括起来!" 实际上,这样做似乎在变量中存储文字双引号,我不想要,例如
C:\Users\Andrew>set bar="hello, world!"&& echo %bar%
%bar%
C:\Users\Andrew>echo %bar%
"hello, world!"
Run Code Online (Sandbox Code Playgroud)"在这之前应该有一个空间&&!" 实际上,这样做似乎在变量中存储了一个尾随空格,这是我不想要的,例如
C:\Users\Andrew>set bar="hello, world!"&& echo %bar%
%bar%
C:\Users\Andrew>echo %bar%
"hello, world!"
Run Code Online (Sandbox Code Playgroud)"都!" > :(
C:\Users\Andrew>set mu="hello, world!" && echo %mu%
%mu%
C:\Users\Andrew>echo (%mu%)
("hello, world!" )
Run Code Online (Sandbox Code Playgroud)我有一个批处理文件,需要将attrib + h命令应用于文件,然后输出到txt文件并在屏幕上显示内容.如果尚未提供或无法找到文件,也应该这样做.到目前为止,我有这个,但无法让它工作:
:TOP
IF EXIST "%1" GOTO COMMAND
) ELSE
(
GOTO ERROR1
:COMMAND
attrib +h %1
SHIFT
GOTO TOP
GOTO END
:ERROR1
IF "%1"=="" GOTO ERROR2
) ELSE
(
GOTO ERROR3
:ERROR2
ECHO.
ECHO No file(s) provided. Please re run the batch file.
GOTO END
:ERROR3
ECHO.
ECHO The file was not found. Please re run the batch file.
GOTO END
:END
Run Code Online (Sandbox Code Playgroud)
这是我的第一个计算机课程,任何帮助将不胜感激.谢谢.
这是一个有趣的主题.我试着玩那里讨论的两件事.
/?无法使用,因为GOTO并CALL打印其帮助消息而不是执行.这是结果:
@echo off
setlocal enableDelayedExpansion
set "label=/?"
call :%%label%%
echo == Test message to check if the CALL or GOTO ( or neither ) command is executed ==
exit /b 0
:/?
echo == CALL or GOTO has been executed ==
exit /b 0
Run Code Online (Sandbox Code Playgroud)
并输出:
Directs cmd.exe to a labeled line in a batch program.
GOTO label
label Specifies a text string used in the batch program as a label. …Run Code Online (Sandbox Code Playgroud) 我坚持这个:我需要在批处理脚本上合并两个文本文件在单个制表符分隔的文本文件中.例如:
文件1:
qwer
tyui
asdf
Run Code Online (Sandbox Code Playgroud)
文件2:
1345
6876
8796
Run Code Online (Sandbox Code Playgroud)
文件3:
qwer 1345
tyui 6876
asdf 8796
Run Code Online (Sandbox Code Playgroud)
事实上,我所需要的只是Unix命令: paste -d "\t" file1 file2 > file3
@echo on并且在批处理文件中@echo off的括号内if块中执行时似乎没有任何影响.这是一个简单的演示:
@echo off
echo Test #1
if 1 == 1 (
@echo on
echo Test #2
@echo off
echo Test #3
)
@echo on
echo Test #4
Run Code Online (Sandbox Code Playgroud)
在命令行上运行上面的输出是:
测试#1
测试#2
测试#3
C:\ mybatchfilelocation> echo测试#4
测试#4
任何人都可以解释这个和/或建议一个解决方法吗?(期望它可能通过大量使用goto和标签来修复,但如果可能的话,我更愿意继续使用括号格式...)
我有以下代码片段:
if "%ARGV:~,1%"==":" echo %ARGV% begins with a colon.
Run Code Online (Sandbox Code Playgroud)
只要变量ARGV包含非空值,或者正确地说,它被定义,一切都按预期工作,因此如果字符串以ARGV冒号开头,echo则执行命令.
但是,只要我清除变量ARGV,就会出现语法错误:
Run Code Online (Sandbox Code Playgroud)echo was unexpected at this time.
这里发生了什么?语法完全正常,但为什么该命令行会失败?
即使是最有用的线程之一,Windows命令解释器(CMD.EXE)如何解析脚本?,因为这些事情没有提供这种行为的解释.
当我在命令提示符中直接执行相同操作时,一切都井然有序.此外,当我尝试使用延迟扩展时,也不会发生错误.
当启用延迟扩展时,(通常)必须正确地转义感叹号以获得文字符号(例如,^^!或者,当介于两者之间""时^!,为了获得文字!).
然而,为什么没有感叹号的逃逸后立即提供的参数范围内,标志着必要的,但即使distructive /R或者/F在开关for循环命令?
考虑到上述转义规则,我创建了以下批处理脚本,for /R并使用名称作为参数创建了一个目录!(在/R选项后面说明):
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "TARGET=excl^!dir"
set "FILE=empty_%RANDOM%.txt"
echo/
echo creating directory: !TARGET!
mkdir "!TARGET!"
echo placing empty file: !TARGET!\%FILE%
> "!TARGET!\%FILE%" break
echo/
echo adequately escaped `^^!`:
for /R "excl^!dir" %%F in ("*.*") do echo(found item: %%~nxF
for /R excl^^!dir %%F in ("*.*") do echo(found item: %%~nxF
echo/
echo improperly escaped `^^!`: …Run Code Online (Sandbox Code Playgroud) batch-file ×10
cmd ×8
windows ×4
syntax ×2
bash ×1
caret ×1
echo ×1
escaping ×1
for-loop ×1
if-statement ×1
piping ×1
syntax-error ×1
windows-7 ×1