Windows批处理脚本将stdout重定向到我们刚刚运行的EXE的stdin

时间:2015-10-08 11:53:21

标签: windows batch-file pipe

我知道在批处理脚本中运行EXE时的正常行为是批处理脚本在继续之前等待EXE退出,但有没有办法让批处理脚本继续执行,但是将其stdout重定向到EXE的stdin?

基本上我正试图实现这个巧妙的技巧或类似的东西......

@ECHO OFF
echo This is a windows batch script...
dir /p C:\

C:\cygwin\bash.exe <--- Do some magic here

echo This is a bash shell script...
ls -la /cygdrive/c/
exit

echo We're back to the windows batch script again
REM Note: being able to return to the batch script isn't important

关于如何实现这一目标的任何想法?感谢。

2 个答案:

答案 0 :(得分:0)

这应该有效:

@ECHO OFF
echo This is a windows batch script...
dir /p C:\

(
ECHO echo This is a bash shell script...
ECHO ls -la /cygdrive/c/
ECHO exit
) | C:\cygwin\bash.exe

echo We're back to the windows batch script again

编辑回复评论

如果您不想为每个bash行添加ECHO,可以使用以下方法:

@ECHO OFF
echo This is a windows batch script...
dir /p C:\

rem Get the number of the first line in this file that start with "###"
for /F "delims=:" %%a in ('findstr /N "^###" "%~F0"') do set "line=%%a" & goto break
:break

rem Pass from that line to end of this file to bash.exe
more +%line% "%~F0" | C:\cygwin\bash.exe 

echo We're back to the windows batch script again
goto :EOF


#################################################################
# The remainder of this file is a bash script running in cygwin #
#################################################################

echo This is a bash script!!
ls -la /cygdrive/c/

编辑#2

我借用了SonicAtom的方法并略微修改它以使其更简单。这是:

@ECHO OFF
setlocal

rem This is a magic trick to run the bottom half of this script as a bash script
if not defined _restarted (
    set _restarted=true
    cmd.exe /Q /D < "%~F0"
    rem Put any cleanup commands here
    echo/
    echo Bash script finished
    pause
    exit /B
)
cls
"C:\cygwin\bin\bash.exe"

#################################################################
# The remainder of this file is a bash script running in cygwin #
#################################################################

echo This is a bash script!!
ls -la /cygdrive/c/

答案 1 :(得分:0)

没有回复?

我自己找到了答案:

test.bat的:

@ECHO OFF

rem This is a magic trick to run the bottom half of this script as a bash script
if not exist _.bat (
    echo @ECHO OFF >_.bat
    echo cmd.exe -c ^< %~nx0 >>_.bat
    _.bat
    rem Put any cleanup commands here
    del _.bat
    echo.
    echo Bash script finished
    pause
    exit /B
)
cls
"C:\cygwin\bin\bash.exe"

#################################################################
# The remainder of this file is a bash script running in cygwin #
#################################################################

echo This is a bash script!!
ls -la /cygdrive/c/

工作原理:

文件以批处理脚本的形式开始。它编写另一个(临时)批处理脚本,该脚本运行另一个cmd.exe shell,将原始批处理文件指向cmd.exe作为stdin。然后,原始批处理文件的行为类似于包含键盘上键入命令的文本文件。它运行bash.exe,并继续为stash提供stdin。唯一的缺点是@ECHO OFF不会在调用bash.exe之前运行的批处理文件中生效。这是因为似乎没有办法在cmd.exe中关闭键盘回显。