시간 초과와 함께 사용자 입력 대기 중
검색해봤는데 제 구글 푸가 약하네요.제가 필요한 것은 콘솔에서 사용자 입력을 요청하고 일정 시간이 지나면 요청 시간이 초과되고 입력이 없으면 스크립트를 계속 실행하는 방법입니다.제가 알기로는 읽기-호스트는 이 기능을 제공하지 않습니다.$host도 마찬가지입니다.UI.PromptForChoice() 또는 $host.UI.원시 UI.키를 읽습니다.조언을 해주셔서 미리 감사드립니다.
편집: 정답을 찾아주신 Lars Truijens님께 감사드립니다.나는 그가 지적한 코드를 가져와서 함수로 캡슐화했습니다.제가 구현한 방식은 사용자가 키를 누를 때와 스크립트 실행이 계속될 때 사이에 최대 1초의 지연이 있을 수 있다는 것을 의미합니다.
function Pause-Host
{
param(
$Delay = 1
)
$counter = 0;
While(!$host.UI.RawUI.KeyAvailable -and ($counter++ -lt $Delay))
{
[Threading.Thread]::Sleep(1000)
}
}
여기서 찾은 내용:
$counter = 0
while(!$Host.UI.RawUI.KeyAvailable -and ($counter++ -lt 600))
{
[Threading.Thread]::Sleep( 1000 )
}
이제는 꽤 오래되었지만 동일한 KeyAvailable 방법을 기반으로 해결한 방법은 다음과 같습니다.
https://gist.github.com/nathanchere/704920a4a43f06f4f0d2
x초 동안 대기하며 다음과 같이 표시됩니다..
최대 대기 시간까지 경과하는 매초마다.키를 누르면 키가 되돌아옵니다.$true
,그렇지않으면$false
.
Function TimedPrompt($prompt,$secondsToWait){
Write-Host -NoNewline $prompt
$secondsCounter = 0
$subCounter = 0
While ( (!$host.ui.rawui.KeyAvailable) -and ($count -lt $secondsToWait) ){
start-sleep -m 10
$subCounter = $subCounter + 10
if($subCounter -eq 1000)
{
$secondsCounter++
$subCounter = 0
Write-Host -NoNewline "."
}
If ($secondsCounter -eq $secondsToWait) {
Write-Host "`r`n"
return $false;
}
}
Write-Host "`r`n"
return $true;
}
사용 방법:
$val = TimedPrompt "Press key to cancel restore; will begin in 3 seconds" 3
Write-Host $val
사전 정의된 키 누르기에서 PowerShell 스크립트를 종료하는 데 추가적인 제약이 있는 현대식 솔루션을 찾는 사용자에게 다음 솔루션이 도움이 될 수 있습니다.
Write-Host ("PowerShell Script to run a loop and exit on pressing 'q'!")
$count=0
$sleepTimer=500 #in milliseconds
$QuitKey=81 #Character code for 'q' key.
while($count -le 100)
{
if($host.UI.RawUI.KeyAvailable) {
$key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyUp")
if($key.VirtualKeyCode -eq $QuitKey) {
#For Key Combination: eg., press 'LeftCtrl + q' to quit.
#Use condition: (($key.VirtualKeyCode -eq $Qkey) -and ($key.ControlKeyState -match "LeftCtrlPressed"))
Write-Host -ForegroundColor Yellow ("'q' is pressed! Stopping the script now.")
break
}
}
#Do your operations
$count++
Write-Host ("Count Incremented to - {0}" -f $count)
Write-Host ("Press 'q' to stop the script!")
Start-Sleep -m $sleepTimer
}
Write-Host -ForegroundColor Green ("The script has stopped.")
샘플 스크립트 출력:
더 많은 조합을 처리하려면 주요 상태에 대한 Microsoft 문서를 참조하십시오.
학점:테크넷 링크
timeout.exe 5
여전히 파워셸에서 작동합니다.키를 누를 때까지 5초 또는 기다립니다.
어쩌면 우아하지 않을 수도 있습니다.하지만 쉽죠.
하지만,
파워셸에서_ISE는 새 명령 프롬프트 창을 팝업하고 즉시 반환되므로 대기하지 않습니다(전원 셸 콘솔에서 해당 콘솔을 사용하고 대기합니다).ISE에서 조금 더 많은 작업을 수행하여 대기 상태로 만들 수 있습니다(계속해서 자체 창이 나타납니다).
if ($psISE) {
start -Wait timeout.exe 5
} else {
timeout.exe 5
}
다음은 다음을 수용하는 키 입력 유틸리티 기능입니다.
- 유효성 검사 문자 집합(1자 정규식).
- 선택적 메시지
- 선택적 시간 제한(초)
일치하는 키 입력만 화면에 반영됩니다.
용도:
$key = GetKeyPress '[ynq]' "Run step X ([y]/n/q)?" 5
if ($key -eq $null)
{
Write-Host "No key was pressed.";
}
else
{
Write-Host "The key was '$($key)'."
}
구현:
Function GetKeyPress([string]$regexPattern='[ynq]', [string]$message=$null, [int]$timeOutSeconds=0)
{
$key = $null
$Host.UI.RawUI.FlushInputBuffer()
if (![string]::IsNullOrEmpty($message))
{
Write-Host -NoNewLine $message
}
$counter = $timeOutSeconds * 1000 / 250
while($key -eq $null -and ($timeOutSeconds -eq 0 -or $counter-- -gt 0))
{
if (($timeOutSeconds -eq 0) -or $Host.UI.RawUI.KeyAvailable)
{
$key_ = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,IncludeKeyUp")
if ($key_.KeyDown -and $key_.Character -match $regexPattern)
{
$key = $key_
}
}
else
{
Start-Sleep -m 250 # Milliseconds
}
}
if (-not ($key -eq $null))
{
Write-Host -NoNewLine "$($key.Character)"
}
if (![string]::IsNullOrEmpty($message))
{
Write-Host "" # newline
}
return $(if ($key -eq $null) {$null} else {$key.Character})
}
function ReadKeyWithDefault($prompt, $defaultKey, [int]$timeoutInSecond = 5 ) {
$counter = $timeoutInSecond * 10
do{
$remainingSeconds = [math]::floor($counter / 10)
Write-Host "`r$prompt (default $defaultKey in $remainingSeconds seconds): " -NoNewline
if($Host.UI.RawUI.KeyAvailable){
$key = $host.UI.RawUI.ReadKey("IncludeKeyUp")
Write-Host
return $key
}
Start-Sleep -Milliseconds 100
}while($counter-- -gt 0)
Write-Host $defaultKey
return $defaultKey
}
$readKey = ReadKeyWithDefault "If error auto exit( y/n )" 'y' 5
다른 옵션: 사용할 수 있습니다.choice
윈도우즈 2000 이후 모든 윈도우즈 버전에 제공되는 셸 명령
Choice /C yn /D n /t 5 /m "Are you sure? You have 5 seconds to decide"
if ($LASTEXITCODE -eq "1") # 1 for "yes" 2 for "no"
{
# do stuff
}
else
{
# don't do stuff
}
스택 오버플로 구문 강조 표시가 파워셸에서 작동하지 않습니다.#
여기서 의미하는 것은 "지켜짐"입니다.
$Host.UI.원시 UI.KeyAvailable이 버그가 있는 것 같아서 [Console]을 사용하면 더 운이 좋았습니다.:사용 가능한 키:
function keypress_wait {
param (
[int]$seconds = 10
)
$loops = $seconds*10
Write-Host "Press any key within $seconds seconds to continue"
for ($i = 0; $i -le $loops; $i++){
if ([Console]::KeyAvailable) { break; }
Start-Sleep -Milliseconds 100
}
if ([Console]::KeyAvailable) { return [Console]::ReadKey($true); }
else { return $null ;}
}
플러싱 인풋 버퍼는 매우 중요합니다, 이것을 사용해보세요, 저에게는 매력적으로 작동했습니다.
function Pause-Host {
param ($Delay = 1)
$host.UI.RawUI.FlushInputBuffer()
While(!$host.UI.RawUI.KeyAvailable -and (0 -lt $Delay--))
{
Write-Host "`rWaiting for $Delay Seconds or Any key Press ..." -NoNewline
Start-Sleep -Seconds 1
}
}
# Optional: Flush last key-press
$host.UI.RawUI.FlushInputBuffer()
스크립트가 종료되기 전에 선택적으로 일시 중지하려면(헤드리스 스크립트 실행 및 오류 출력 일시 중지에 유용) Nathanheer의 답변을 다음과 같이 추가했습니다.
if ([Console]::KeyAvailable) { $pressedKey = [Console]::ReadKey($true); read-host; break; }
elseif ($secondsCounter -gt $secondsToWait) {
Write-Host "`r`n"
return $false;
}
언급URL : https://stackoverflow.com/questions/150161/waiting-for-user-input-with-a-timeout
'programing' 카테고리의 다른 글
AJAX 호출에 의해 삽입된 IE 8에서 HTML5 요소를 "활성화"하는 방법은 무엇입니까? (0) | 2023.09.05 |
---|---|
Spring에서 속성의 문자열 배열을 바인딩하는 방법은 무엇입니까? (0) | 2023.09.05 |
Powershell: Receive-Job에서 출력 가져오기 (0) | 2023.09.05 |
구성 파일에 일반 텍스트로 mysql 암호를 저장하는 것보다 더 나은 접근 방식이 있습니까? (0) | 2023.09.05 |
날짜 사이의 Laravel $q->where() (0) | 2023.09.05 |