如何在PowerShell终端右上角实现后台运行的类Bash时钟
在PowerShell终端右上角实现后台运行的时钟
问题背景
需要实现和以下Bash脚本功能一致的PowerShell时钟:
while true; do echo -ne "\e[s\e[0;$((COLUMNS-7))H\e[30;47m$(date +'%H:%M:%S')\e[0m\e[u"; sleep 1; done &
该Bash脚本会在终端右上角后台运行时钟,不影响终端正常使用。但自行编写的PowerShell代码会阻塞终端,使用Start-Process -NoNewWindow也无法成功。
失败原因分析
- 直接调用时钟函数会阻塞当前PowerShell线程,导致无法进行其他操作。
- 使用
Start-Process时,新启动的PowerShell进程无法访问当前会话中定义的时钟函数,因此执行失败。
解决方案
使用PowerShell的后台线程作业(Start-ThreadJob),它能在当前会话的后台线程中运行时钟,既不阻塞终端,又能直接操作控制台光标。
完整代码
function Show-Clock { while ($true) { # 实时获取窗口宽度,适配窗口大小变化 $width = [console]::WindowWidth $x = $width - 8 # "HH:MM:SS" 占8个字符宽度 $y = 0 $time = (Get-Date).ToString("HH:mm:ss") # 保存当前光标位置 [console]::Write("`e[s") # 移动光标到右上角位置 [console]::SetCursorPosition($x, $y) # 输出带样式的时间 Write-Host $time -BackgroundColor White -ForegroundColor Black -NoNewline # 恢复光标到之前的位置 [console]::Write("`e[u") Start-Sleep -Seconds 1 } } # 启动后台线程作业 Start-ThreadJob -ScriptBlock ${function:Show-Clock} | Out-Null
代码说明
Start-ThreadJob:在当前PowerShell会话的后台线程中运行函数,不会阻塞主终端线程。- 实时获取
[console]::WindowWidth:适配终端窗口大小变化,时钟始终保持在右上角。 - 使用ANSI转义序列
\e[s和\e[u:保存和恢复光标位置,避免时钟输出干扰当前输入内容(和Bash脚本逻辑一致)。 Out-Null:隐藏作业启动的输出信息,保持终端整洁。
停止时钟
如果需要停止后台运行的时钟,执行以下命令:
Get-Job | Stop-Job Get-Job | Remove-Job
内容的提问来源于stack exchange,提问作者roooot
相关产品推荐
相关产品推荐

