2015-04-02 3 views
0

Я пытался создать файл, который вводит время ввода пользователя. я мог бы получить этот файлSet/p Мгновенно

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 отсчитывает прошли secconds, так как она началась.

(: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

Прежде чем ответить на ваш вопрос, я должен указать, что цикл 1000 раз не обязательно означает, что вы приостановили на 1 секунду. Есть лучшие способы спать - timeout /t seconds в Vista или новее, или ping -n seconds+1 localhost или choice /t seconds в XP. Вы также должны избегать топания на 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, который будет написан только один раз, а затем удален в конце.

@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() 
); 
Смежные вопросы