奇怪的redirect在批处理/ Powershell多边形

在尝试重写batch file时,我正在研究使用PowerShell的可能性。 我用它的主要问题是.ps1文件默认情况下不可执行。 我在这里find了一个解决scheme,我将在下面复制,但是我对第一行的语法非常困惑:

 <# : batch script @echo off setlocal cd %~dp0 powershell -executionpolicy remotesigned -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))" endlocal goto:eof #> # here write your powershell commands... 

以下是我从testing中得知的内容:

  • <#:之间的空格是必需的,尽pipe可以有多个。
  • 它也可以有一个0-9的数字,例如3<# : :,这让我怀疑有一些涉及redirect和标签的怪异。
  • 冒号后面的文本被忽略,不是必需的
  • 如果我在它之前添加一个命令,如git <# : batch script ,shell显示它试图评估git : batch script 0<#并且找不到指定的文件
  • #改为有效的文件名使得投诉消失(自然地)
  • 尝试在交互式会话中运行该行实际上会导致它抱怨找不到指定的文件,但是从脚本运行它(即使它是.cmd文件中的唯一一行)将静默地成功

最后一个子弹是我试图找出的部分。 环境有什么不同? 我的理解是,问题的一部分是运行一个bat文件被parsing,就好像每一行都是手动input的。 为什么它没有抱怨通过脚本调用#是一个无效的文件?

“…运行一个bat文件被解析,就好像每一行都是手动输入的。

不,解析器规则有时在命令行和批处理文件之间是不同的,在这种情况下,差异是至关重要的。

它抱怨#在命令行中是一个无效的文件,而不是在批处理文件中,因为<# :构造(对于批解析器)只是一个重定向的标签 。 您在goto :labelcall :label使用的同一种call :label

这意味着重定向,即不在批处理文件中执行的与重定向关联的“命令”是一个标签,在命令行中执行,因为在命令行中不能有标签。

诀窍是,你需要一个有效的构造,PowerShell和批处理。
对于PowerShell而言,只有<#对于打开多行注释非常重要。

对于批处理,你需要的东西将是有效的代码,但是echo on状态echo on下是不可见的。
因此,冒号在这种情况下是完美的,因为标签行将不会显示,即使是echo on

当您用REM替换冒号时,您可以看到解析器的结果。

 <# REM Batch script 

输出:

 c:\Temp>REM batch script 0<# 

#是一个有效的文件名,但文件本身从来没有被认同。