我一直在尝试创建一个用户输入的文件。 我可以得到这个文件
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做某事。完全没有输入,甚至没有输入。
所以,如果我没有按任何键并且已经过了一分钟,那么它会打印一分钟而没有输入。
我希望这对你有用。
答案 0 :(得分:0)
在我回答你的问题之前,我需要指出循环1000次并不一定意味着你暂停了1秒钟。有更好的睡眠方式 - 在Vista或更新版本中timeout /t seconds
,或在XP中使用ping -n seconds+1 localhost
或choice /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()
);