如何模拟批处理脚本
How to simulate a batch script
我需要设置一个基于批处理脚本的 PowerShell 脚本。原始批处理脚本如下所示:
call %SYSTEMROOT%\setup_Env.BAT
command_name command_arguments
该命令取决于正在设置的 setup_ENV.BAT
中的环境变量。
$tempFile = [IO.Path]::GetTempFileName()
$script = "%SYSTEMROOT%\setup_Env.BAT"
cmd /c " $script && set > $tempFile "
cmd /c " command_name command_arguments"
我收到错误:
cmd : 'command_name is not recognized as an internal or external command,...
如果在 PowerShell 中有更好的方法来执行此操作,我愿意接受。
您需要将 单个 命令行传递给 cmd
以使其工作:
cmd /c "call %SYSTEMROOT%\setup_Env.BAT && command_name command_arguments"
正如 Ansgar Wiechers 指出的那样,每个 cmd
调用都在子进程中运行,并且在子进程中所做的任何环境修改对调用进程都是不可见的,因此对未来的子进程也是不可见的进程。
相比之下,在上面的单个命令行中,setup_Env.BAT
执行的环境变量修改在 command_name
执行时对 可见.
警告:如果 command_arguments
包含对环境 %...%
样式的引用 setup_Env.BAT
中定义的变量,需要更多工作:
- 将
%...%
样式引用更改为 !...!
样式引用。
另外调用 cmd
和 /v
以启用延迟变量扩展(相当于脚本中的 setlocal enabledelayedexpansion
`:
cmd /v /c "call %SYSTEMROOT%\setup_Env.BAT && command_name args_with_delayed_var_refs"
警告:如果 command_arguments
恰好包含 !
个字符,上述 可能仍无法按预期工作。应该被视为 literals(and/or command_name
是另一个包含此类的批处理文件)。
在那种情况下,最简单的方法是简单地在临时文件中重新创建整个批处理文件并调用它:
# Get temp. file path
$tempBatFile = [IO.Path]::GetTempFileName() + '.bat'
# Write the content of the temp. batch file
@'
@echo off
call %SYSTEMROOT%\setup_Env.BAT
command_name command_arguments
'@ | Set-Content $tempBatFile
# Execute it.
& $tempBatFile
# Clean up.
Remove-Item -LiteralPath $tempBatFile
我需要设置一个基于批处理脚本的 PowerShell 脚本。原始批处理脚本如下所示:
call %SYSTEMROOT%\setup_Env.BAT
command_name command_arguments
该命令取决于正在设置的 setup_ENV.BAT
中的环境变量。
$tempFile = [IO.Path]::GetTempFileName()
$script = "%SYSTEMROOT%\setup_Env.BAT"
cmd /c " $script && set > $tempFile "
cmd /c " command_name command_arguments"
我收到错误:
cmd : 'command_name is not recognized as an internal or external command,...
如果在 PowerShell 中有更好的方法来执行此操作,我愿意接受。
您需要将 单个 命令行传递给 cmd
以使其工作:
cmd /c "call %SYSTEMROOT%\setup_Env.BAT && command_name command_arguments"
正如 Ansgar Wiechers 指出的那样,每个 cmd
调用都在子进程中运行,并且在子进程中所做的任何环境修改对调用进程都是不可见的,因此对未来的子进程也是不可见的进程。
相比之下,在上面的单个命令行中,setup_Env.BAT
执行的环境变量修改在 command_name
执行时对 可见.
警告:如果 command_arguments
包含对环境 %...%
样式的引用 setup_Env.BAT
中定义的变量,需要更多工作:
- 将
%...%
样式引用更改为!...!
样式引用。 另外调用
cmd
和/v
以启用延迟变量扩展(相当于脚本中的setlocal enabledelayedexpansion
`:cmd /v /c "call %SYSTEMROOT%\setup_Env.BAT && command_name args_with_delayed_var_refs"
警告:如果 command_arguments
恰好包含 !
个字符,上述 可能仍无法按预期工作。应该被视为 literals(and/or command_name
是另一个包含此类的批处理文件)。
在那种情况下,最简单的方法是简单地在临时文件中重新创建整个批处理文件并调用它:
# Get temp. file path
$tempBatFile = [IO.Path]::GetTempFileName() + '.bat'
# Write the content of the temp. batch file
@'
@echo off
call %SYSTEMROOT%\setup_Env.BAT
command_name command_arguments
'@ | Set-Content $tempBatFile
# Execute it.
& $tempBatFile
# Clean up.
Remove-Item -LiteralPath $tempBatFile