将带有变量存在性测试的 Windows 批处理脚本块传送到另一个命令

问题描述

我正在尝试使用以下代码来测试管道变量是否存在,这是我想要执行的包含脚本块内其他代码的真实代码的简化,但这演示了问题:

( if defined some_variable echo ok ) | more
echo was unexpected at this time

它给了我消息“此时回声是意外的。”在“if”语句后引用带括号并不能解决问题,它只是抱怨括号

( if defined some_variable ( echo ok ) ) | more
( was unexpected at this time.

“if”语句的两种变体都可以在不在管道中的代码块中使用。

if defined some_variable echo ok
ok
if defined some_variable ( echo ok )
ok

此外,我可以执行代码块但输出文件,这可以捕获脚本块的输出,特别是即使脚本块中有多行代码

( if ok defined some_variable echo ok ) > some_text_file.txt

这种“if”风格在脚本块到管道结构中起作用:

( if 1==1 echo ok ) | more
ok
( if NOT 1==2 echo ok ) | more
ok

但我不明白为什么使用 'defined' 关键字的存在性测试完全破坏了这种管道结构。

我的最终目标是让以下类型的代码在批处理脚本中工作(它比下面的示例有更多的事情要做),但问题归结为开头提到的简化炸弹。下面的代码将作为批处理脚本将输出回显到命令提示符和日志文件,但脚本块中的变量检查会破坏它。

( 
  echo some_stuff_like_a_program_header
  
  #test existence of a variable and if not defined earlier in script then echo some stuff
  if NOT defined some_variable then_alert_user_with_error_msg
  
  if some_variable==some_value (do_some_stuff) else (do_other_stuff)
  
) | powershell.exe -command '& { $input | tee-object -file out.log }'

解决方法

这是解析器的一个bug,if语句会被压缩为 if definedsome_variable echo ok
您会看到 definedsome_variable

之间的空格已删除

可以通过后期变量展开来解决。

set "myLine=if defined path echo ok"
echo pipe | ( %%myLine%%)

或者使用转义空格(来自@enjoying SO:Why does the error message appear when IF comparison is in the piped block command?

echo pipe | ( if defined ^  path echo ok )

要查看内部发生的情况,您可以尝试此调试构造

@echo off
setlocal
(set \n=^
%=empty=%
)
set "debug=echo ### %%cmdcmdline%% ^) %%\n%%"
echo dummy | (
    %debug%
    if defined some_variable echo ok
)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...