英文:
Can we call Bat command within powershell without calling/invoking a bat file?
问题
可以在PowerShell中调用Bat命令而不调用/调用Bat文件吗?
例如,Bat脚本:
@echo [off]
echo sample batch script
pause
在PowerShell中本身
命令必须被执行。
英文:
Can we call Bat command within powershell without calling/invoking a bat file?
For example bat script:
@echo [off]
echo sample batch script
pause
In powershell itself
Commands must be executed.
答案1
得分: 2
以下是翻译好的部分:
你可以模拟大多数批处理操作。
- 例如
PAUSE
。 - 而
ECHO
类似于Write-Host
和$Var | Out-Host
。
此外,你可以使用 cmd.exe --% /c
调用批处理命令,但是,一旦 cmd.exe 退出,执行命令的环境就消失了,其中设置的任何环境变量也会消失。
另一方面,cmd.exe
的输出可以保存到变量中。
在这个示例中:
- 在Stop-Parsing标记之后的所有内容都会未经处理地传递给CMD。
dir
命令的路径是通过首先设置一个环境变量$Env:DirPath = 'C:\Users\public'
,然后在批处理中检索环境变量%DirPath%
动态提供的。- 使用
$Var = $(<code>)
将输出保存在 $Var 中。
注意: 闭括号不在 cmd.exe --%
行的末尾,因为如果在末尾,它将被 PowerShell 忽略。
$Env:DirPath = 'C:\Users\public'
$Var = $(
cmd.exe --% /c dir "%DirPath%" /w
)
$Var
你还应该能够在 cmd.exe --%
命令中使用 &
执行多个批处理命令,但我还没有进行过实验,所以不确定会如何运行。
英文:
You can emulate most things BATCH.
- For example
PAUSE
. - And
ECHO
is similar toWrite-Host
and$Var | Out-Host
.
Also, you can call BATCH commands with cmd.exe --% /c
, BUT, as soon as cmd.exe exits, the environment the command was executed in is gone - along with any environment variables that were set.
On the other hand, cmd.exe
's output can be saved to a variable.
In this example:
- Everything after the Stop-Parsing token is passed unprocessed to CMD.
- The path given to
dir
is dynamically provided by first setting an environment variable$Env:DirPath = 'C:\Users\public'
, and then retrieved the environment variable in BATCH%DirPath%
. - Uses
$Var = $(<code>)
to save output in $Var.
NOTE: The closing parentheses is NOT at the end of the cmd.exe --%
line, because, if it was, it would be ignored by PowerShell.
$Env:DirPath = 'C:\Users\public'
$Var = $(
cmd.exe --% /c dir "%DirPath%" /w
)
$Var
You should also be able to use &
in the cmd.exe --%
command to execute more than one BATCH command, but I haven't experimented with that, so not sure how that would work out.
答案2
得分: 1
-
无法在PowerShell中直接执行批处理命令,因为PowerShell无法理解它们。
-
虽然有一个小子集的命令在
cmd.exe
(批处理文件的解释器)和PowerShell中具有相同的名称,PowerShell通过为其不同命名的命令提供_别名_(例如,dir
用于Get-ChildItem
)来提供对这些少数命令的调用仅在所有但最简单的情况下才能正常工作,因为PowerShell的参数语法与cmd.exe
的语法根本不同。 -
可以通过
cmd.exe
的CLI执行批处理命令,即通过**cmd /c
(运行cmd /?
以获取详细信息)或通过将命令_管道_到cmd.exe
**(... | cmd
),但请注意以下事项:-
与批处理文件一样,这些调用在一个_子_进程中运行,因此对环境变量的修改对调用者是不可见的,例如。
-
这些命令被解释为_交互式_
cmd.exe
会话中的命令,这意味着for
循环必须使用%i
而不是%%i
,例如。 -
传递_多个_批处理命令有_严重限制_:
-
使用
cmd /c
,您只能传递_单个_行(任何额外的行将被忽略),因此您必须使用cmd.exe
的&
运算符来顺序执行多个命令,这仅在这些命令不依赖于变量时才起作用_相互_。OK - 两个命令不相互依赖。
cmd /c 'ver & date /t'
!! NOT OK - %FOO%的值不会被echo调用看到
cmd /c '(Set FOO=bar) & echo %FOO%'
-
但是,您可以通过
/v
选项启用延迟变量扩展功能,在这种情况下,使用!...!
而不是%...%
有效:OK - 由于/v和!FOO!
cmd /v /c '(Set FOO=bar) & echo !FOO!'
-
此外,您可以使用一个可展开(双引号引起的)字符串(
"..."
)来嵌入cmd /c
调用中_PowerShell_变量的值,作为Darin的回答中显示的--%
技术的替代方法;如果需要嵌入"
字符,请将其转义为`"
(或""
):$foo = 'bar' # 定义一个PowerShell变量
cmd /c "echo $foo" # 将其值嵌入“...”字符串
-
-
-
使用多行管道输入:
-
即使您将多行输入字符串以
@echo off
开头,您仍然会看到cmd.exe
的启动横幅(Microsoft Windows [Version ...]
)和一个提示字符串(例如,C:\>
),并且每个命令的源代码行将在执行结果之前打印出来。 -
除非代码使用显式的
exit
调用退出,否则cmd.exe
的退出代码将_不_反映最后一个执行的命令的退出代码。 -
要了解更多信息以及在幕后创建一个_临时批处理文件_以避免这些限制的帮助函数,请参阅此回答。
-
这是一个使用here-string来将多个命令传递给
cmd.exe
的示例;如上所述,您将看到启动横幅和一个提示字符串,并且每个命令的输出之前将打印出源代码行:@'
@echo off
ver
date /t
Set FOO=bar
echo %FOO%
exit
'@ | cmd.exe
-
英文:
-
You cannot execute batch-file commands directly in PowerShell, because PowerShell doesn't understand them.
- While there is a small subset of commands that have the same name in both
cmd.exe
(the interpreter of batch files) and PowerShell, by way of PowerShell providing aliases for its differently named commands (e.g.,dir
forGet-ChildItem
), calls to these few commands only work the same in all but the simplest cases, given that PowerShell's parameter syntax differs fundamentally from that ofcmd.exe
- While there is a small subset of commands that have the same name in both
-
You can execute batch-file commands via
cmd.exe
's CLI, namely either viacmd /c
(runcmd /?
for details) or by piping commands tocmd.exe
(... | cmd
), but note the following:-
Like batch files, such calls run in a child process, so that modifications to environment variables wouldn't be seen by the caller, for instances.
-
The commands are interpreted as in interactive
cmd.exe
sessions, which notably means thatfor
loops must use%i
rather than%%i
, for instance. -
Passing multiple batch-file commands has severe limitations:
-
With
cmd /c
, you can only pass a single line (any additional lines are ignored), so you must usecmd.exe
's&
operator to sequence multiple commands, which only works if these commands do not depend on each other with respect to variables.# OK - the two commands aren't interdependent. cmd /c 'ver & date /t' # !! NOT OK - the %FOO% value isn't seen by the echo call cmd /c '(Set FOO=bar) & echo %FOO%'
-
However, you can enable the delayed-variable-expansion feature via the
/v
option, in which case using!...!
instead of%...%
does work:# OK - thanks to /v and !FOO! cmd /v /c '(Set FOO=bar) & echo !FOO!'
-
Separately, you can use an expandable (double-quoted) string (
"..."
) in order to embed the value of PowerShell variables in thecmd /c
call, as an alternative to the--%
technique shown in Darin's answer; if you need to embed"
characters, escape them as`"
(or""
):$foo = 'bar' # define a PowerShell variable cmd /c "echo $foo" # embed its value in the "..." string
-
-
With multiline pipeline input:
-
Even if you start your multiline input string with
@echo off
, you will invariably seecmd.exe
's startup banner (Microsoft Windows [Version ...]
) and one prompt string (e.g,C:\>
), and the source code line of each command will print either way before the result of its execution. -
Unless the code exits with an explicit
exit
call, thecmd.exe
's exit code will not reflect the exit code of the last command executed. -
For more information as well as a helper function that creates a temporary batch file behind the scenes to avoid these limitations, see this answer
-
Here's an example that uses a here-string to feed multiple commands to
cmd.exe
; as noted, you'll see the startup banner and one prompt string, and the source-code lines will print before each command's output:@' @echo off ver date /t Set FOO=bar echo %FOO% exit '@ | cmd.exe
-
-
-
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论