批处理/ Powershell多语言中的奇怪重定向

Mat*_*ucy 7 windows powershell cmd batch-file

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

<# : 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...
Run Code Online (Sandbox Code Playgroud)

这是我从测试中得知的:

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

最后一颗子弹是我想弄清楚的部分.环境有什么不同?我的理解是问题的一部分是运行bat文件被解析,好像每条线都是手动输入的.#当通过脚本调用时,为什么不抱怨是无效文件?

MC *_* ND 7

"...运行一个bat文件被解析,好像每条线都是手动输入的."

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

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

这意味着重定向(在批处理文件中不作为与重定向关联的"命令"执行的标签)在命令行中执行,因为您在命令行中没有标签.