立即设置/ p

时间:2015-04-02 20:55:58

标签: batch-file input time call

我一直在尝试创建一个用户输入的文件。 我可以得到这个文件

start /min b1.bat
(:b1.bat)
@echo off
cls
set num=0
:time
set /a num=%num%+1
echo %num% >waiter.txt
set time=0
:wait
cls
set /a time=%time%+1
if "%time%" equ "1000" goto time
goto wait

这里,b1.bat计算自启动以来经过的秒数。

(:b2.bat)
cls
:begin
set /p time= <waiter.txt
echo %time%    
if "%time%" equ "5" echo Five secconds.
set /p cho=Input:
goto begin

我想知道如果没有给出一段时间的输入,如何使b2.bat做某事。完全没有输入,甚至没有输入。

所以,如果我没有按任何键并且已经过了一分钟,那么它会打印一分钟而没有输入。

我希望这对你有用。

1 个答案:

答案 0 :(得分:0)

在我回答你的问题之前,我需要指出循环1000次并不一定意味着你暂停了1秒钟。有更好的睡眠方式 - 在Vista或更新版本中timeout /t seconds,或在XP中使用ping -n seconds+1 localhostchoice /t seconds。您还应该避免踩踏existing environment variables,例如%time%

要回答您的问题,没有优雅的方法可以为set /p设置超时。但是,您可以使用start /b在同一窗口中启动后台线程,以便在一个时间间隔内回显事物。您可以使用waitfor(仅限Vista或更新版本)在活动线程和后台之间设置线程间通信以重置计时器,并在waiter.txt消失时将帮助程序线程设置为自毁。

只要您在同一个窗口中启动一个帮助程序线程,也可以将waiter.txt线程放在那里。为什么在重用已有的窗口时会产生最小化的窗口?由于我们在同一窗口中合并进程线程,因此可以更进一步将所有脚本合并到一个脚本中,该脚本使用不同线程的不同参数重新启动自身。

@echo off
setlocal

if "%~1"=="" (
    >waiter.txt echo 0
    start /b "" "%~f0" helper1
    start /b "" "%~f0" helper2
) else goto %~1

:begin
cls
set /p "seconds="<waiter.txt
echo Alive for %seconds%s.

:read-host
set "cho="
set /p "cho="
if not defined cho goto read-host

rem // delayed expansion prevents evaluation of special characters in user input
setlocal enabledelayedexpansion
for %%c in (quit exit die EOL) do if /i "!cho!"=="%%c" (
    del waiter.txt
    echo OK, bye!
)
rem // send signal to helper2 acknowledging entry
waitfor /s %computername% /si UserEntry >NUL 2>NUL
if not exist waiter.txt exit /b

rem // ========================================
rem // Do something meaningful with !cho! here.
rem // ========================================
endlocal

goto begin

rem // formerly b1.bat
:helper1
set "num=0"
:helper1_loop
timeout /t 1 /nobreak >NUL 2>NUL
set /a num+=1
if not exist waiter.txt exit
>waiter.txt echo %num%
goto helper1_loop

:helper2
if not exist waiter.txt exit
waitfor /t 60 UserEntry >NUL 2>NUL || (
    echo A minute has passed without input.
)
goto helper2

为了额外的功劳,让我们摆脱waiter.txt。我不确定这种偏执是否成立,但我相信硬盘行业可以承受有限数量的写入。每秒重写一次waiter.txt可能需要几个小时让我烦恼。因此,让我们创建一个混合Jscript块来计算脚本开始和现在之间经过的秒数。

为了控制后台帮助程序线程的执行,我们仍然使用临时文件,但我们将使用只会写入一次的lock file,然后在最后删除。 / p>

@if (@CodeSection == @Batch) @then

@echo off
setlocal

if "%~1"=="" (
    rem // relaunch self as helper if lock file is writeable
    2>NUL (>"%~dpn0.lock" type NUL) && start /b "" "%~f0" helper

    rem // create a lock file for the duration of the main runtime
    rem // Credit: Dave Benham -- https://stackoverflow.com/a/27756667/1683264
    8>&2 2>NUL (2>&8 9>"%~dpn0.lock" call :init) || (
      echo Only one instance is allowed.
      timeout /t 3 /nobreak >NUL
      exit /b
    )
) else goto %~1

rem // cleanup and end main runtime
del "%~dpn0.lock" >NUL 2>NUL
waitfor /s %computername% /si UserEntry >NUL 2>NUL
exit /b

:init
rem // set %start% to current epoch
call :jscript start

:begin
cls
call :jscript seconds
echo Alive for %seconds%s.

:read-host
set "cho="
set /p "cho="
if not defined cho goto read-host

rem // delayed expansion prevents evaluation of special characters in user input
setlocal enabledelayedexpansion
for %%c in (quit exit die EOL) do if /i "!cho!"=="%%c" (
    echo OK, bye!
    exit /b
)
rem // send signal to helper2 acknowledging entry
waitfor /s %computername% /si UserEntry >NUL 2>NUL

rem // ========================================
rem // Do something meaningful with !cho! here.
rem // ========================================
endlocal

goto begin

:helper
del "%~dpn0.lock" >NUL 2>NUL
if not exist "%~dpn0.lock" exit
waitfor /t 60 UserEntry >NUL 2>NUL || (
    echo A minute has passed without input.
)
goto helper

:jscript
for /f %%I in ('cscript /nologo /e:JScript "%~f0" "%start%"') do set "%~1=%%I"
goto :EOF

@end // end batch / begin JScript hybrid code
WSH.Echo(
    WSH.Arguments(0)
    ? Math.round((new Date() - WSH.Arguments(0)) / 1000)
    : new Date().getTime()
);