输入批处理文件并将该输入输出到另一个批处理文件

时间:2016-01-29 17:27:39

标签: windows batch-file cmd

对于凌乱的标题感到抱歉。

我想有效地从另一个批处理文件/窗口获取输入(例如:批处理文件中的选择命令)并将其发送到另一个批处理文件。基本上它会在另一个窗口中“键入”它。现在,我不能让第一个批处理文件打开一个新文件,因为如果我这样做,我只会打开另一个java实例

第一批文件的代码:

:menu
cls
echo.
echo Please select option using keys 1 or 2:
echo. [1] Start server
echo. [2] Stop server
echo. [3] Say "hi"!
choice /C 12 /N
if %errorlevel%==1 goto start-server
if %errorlevel%==2 goto stop-server
if %errorlevel%==3 goto test-command
goto menu

:start-server
echo Starting server...
start start.bat
pause
goto menu

:stop-server
echo Stopping server
echo stop > task start.bat
pause
goto menu

:test-command
echo say hi > task start.bat
pause
goto menu

第二批文件的代码:

@echo off

java -Xms1024M -Xmx2048M -jar spigot_server.jar
pause

echo stop > task start.bat

这样的东西

有没有人对如何实现这一点有任何想法?我愿意为第一个文件使用除批处理之外的任何东西(因为第二个文件要求它是一个批处理脚本),但我不想下载任何东西。

2 个答案:

答案 0 :(得分:1)

我假设你的java服务器是一个接受重定向stdin输入的控制台进程。我还假设如果从文件读取并且它到达输入文件的末尾,您的服务器进程将终止。我还假设你不想修改你的java代码。

您无法使用管道在两个窗口之间进行通信。但是你可以使用一个文件。

您的主批处理脚本可以将命令写入服务器读取的输入文件。但是服务器无法直接读取命令。需要使用发件人批处理脚本将命令中继到服务器。

主脚本通过启动发送脚本启动服务器,输入重定向到输入文件,发送脚本输出通过管道传送到服务器进程。

发送脚本是一个循环,它重复使用FOR / F通过FINDSTR读取输入文件。 FINDSTR读取stdin(已经重定向到输入文件)。这样做的原因是因为FINDSTR每次调用时都不会重置文件指针。如果没有新命令,则它不返回任何内容。但是如果在输入文件中添加了一行,那么FINDSTR会将其拾起。

添加到输入文件的每个命令都包含两个由冒号分隔的部分。

  • 发送批处理脚本的命令
    • GO告诉发送脚本它是服务器的正常命令
    • EXIT告诉发送脚本它应该关闭
  • 服务器命令

我选择将主脚本和发件人脚本合并到一个脚本中。该脚本通过使用:send参数调用自身来启动发送方。如果第一个参数是:send,则它将分支到发送者代码。

我没有你的java服务器代码。因此,出于演示目的,我使用了cmd.exe作为我的"服务器"。显然,我的:菜单中的命令适用于cmd.exe。您可以替换您的java程序并适当地更改命令。

请注意,服务器窗口在启动时会自动窃取焦点。您必须单击父窗口才能重新获得焦点,以便输入命令。

@echo off
if "%~1" equ ":send" goto :send

setlocal
set "inputFile=input.txt"
set "serverCommand=cmd.exe"

:initMenu
echo(
echo Press one of the option keys
echo  [S] Start server
echo  [Q] Quit
choice /c SQ /n
if errorlevel 2 exit /b
echo Starting server...
echo(
echo You must click on this main window to regain focus.
copy nul "%inputFile%" >nul
start "" cmd /c ""%~f0" :send <"%inputFile%" | cmd"
call :menu
echo Server stopped
goto :initMenu

:menu
echo Press one of the option keys
echo  [D] Date
echo  [T] Time
echo  [P] Ping
echo  [S] Stop server
choice /c DTPS /N
>>"%inputFile%" (
  if errorlevel 4 (
    echo exit:exit
    exit /b
  ) else if errorlevel 3 (
    echo go:ping /n 5 localhost
  ) else if errorlevel 2 (
    echo go:time /t
  ) else (
    echo go:date /t
  )
)
echo(
goto :menu

:send
for /f "delims=: tokens=1*" %%A in ('findstr "^"') do (
  echo(%%B
  if /i %%A equ exit %%A
)
goto :send

请注意:send例程不断轮询stdin,因此它会将处理器(或处理器核心)挂起接近100%。你可以在循环中添加一个PING延迟,这样它就不会占用CPU资源,但服务器也不会那么响应。

如果您的服务器进程在到达重定向输入结束时没有自动终止,那么您不需要发件人批处理。您只需使用

在主脚本中启动服务器即可
start cmd /c ""yourServerCommand <"%inputFile%""

或者如果它当前在到达文件末尾时终止,但您愿意修改服务器代码,那么您仍然可以执行上述操作。你可以修改你的java代码来连续轮询输入,只读取一行,如果不是在文件的末尾。该进程只有在收到某种类型的退出命令时才会终止。

如果您的服务器不是控制台进程,那么您需要AutoIt之类的命令来向服务器窗口发送命令。或者您可以使用VBScript或JScript以及SendKeys method

推出自己的解决方案

即使您的服务器进程是控制台进程,您仍然可能希望使用AutoIt或SendKeys,因为它更直接。

答案 1 :(得分:-2)

这是一种使用参数的方法,正如@Dennis van Gils建议的那样。

<强> FIRST.BAT

@echo off
:menu
cls
echo.
echo Please select option using keys 1 or 2:
echo. [1] Start server
echo. [2] Stop server
echo. [3] Say "hi"!
choice /C 123 /N
if %errorlevel%==1 goto start-server
if %errorlevel%==2 goto stop-server
if %errorlevel%==3 goto test-command
goto menu

:start-server
second.bat start
goto menu

:stop-server
second.bat stop
goto menu

:test-command
second.bat hi
goto menu

<强> SECOND.BAT

@echo off
if "%1"=="start" (
    echo Starting Server...
    rem java -Xms1024M -Xmx2048M -jar spigot_server.jar
)

if "%1"=="stop" (
    echo Stopping Server...
)

if "%1"=="hi" (
    echo Hi there!
)