Powershell 低调酷
Source: Dev.to
PowerShell 常常因为不如其他更流行的 shell 而被忽视,但它提供了强大的功能,能够简化本地开发工作流。下面是一份逐步指南,展示如何使用 PowerShell 为 Go 项目构建文件监视器,从基本设置到使用后台作业处理长时间运行的进程。
什么是 PowerShell?
PowerShell 同时是基于 .NET 运行时的命令行 shell 和脚本语言。与传统的 Unix shell(例如 Bash)通过管道传递纯文本不同,PowerShell 的管道传递 对象,从而可以在 shell 中直接进行更丰富的数据操作。
设置监视器目录
# Create a directory for the watcher
mkdir watcher
PowerShell 提供 New-Item cmdlet 用于创建项,但出于便利常用的别名如 mkdir 也可使用。
# Navigate into the directory
cd watcher
# Create a placeholder Go source file
ni main.go
# Create the PowerShell script that will perform the watching
ni watcher.ps1
调整执行策略
PowerShell 的执行策略决定脚本是否可以运行。继续操作前请确保已将其设置为 RemoteSigned(或更宽松的级别)。
# View the current policy
Get-ExecutionPolicy
# If needed, set it to RemoteSigned
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
示例 Go 程序
创建一个简单的 Go 程序,打印 “Hello World”。将其保存为 main.go,放在 watcher 文件夹中。
package main
import "fmt"
func main() {
fmt.Println("Hello World")
}
基础监视脚本(同步)
下面的 PowerShell 脚本会监视当前目录(及子目录)下所有 .go 文件。当检测到变化时,重新运行 Go 程序。
# watcher.ps1
# Path to the Go file (can be overridden later)
$path = "main.go"
Write-Host 'GoWatcher *Press CTRL+C to quit*'
$dirname = "."
$files = Get-ChildItem $dirname -Filter "*.go" -Recurse
# Initial run
go run $path
# Compute an initial signature (hash) of all Go files
$signature = $files | Get-FileHash -ErrorAction SilentlyContinue |
Sort-Object Path | Out-String
while ($true) {
$current_signature = $files | Get-FileHash -ErrorAction SilentlyContinue |
Sort-Object Path | Out-String
if ($signature -ne $current_signature) {
Write-Host 'File change detected: Restarting...'
go run $path
$signature = $current_signature
}
Start-Sleep -Milliseconds 300
}
运行脚本:
.\watcher.ps1
为文件路径添加参数
通过接受 Go 文件路径作为命令行参数,使脚本更具灵活性。
# watcher.ps1 (updated)
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
$path
)
Write-Host 'GoWatcher *Press CTRL+C to quit*'
$dirname = "."
$files = Get-ChildItem $dirname -Filter "*.go" -Recurse
go run $path
$signature = $files | Get-FileHash -ErrorAction SilentlyContinue |
Sort-Object Path | Out-String
while ($true) {
$current_signature = $files | Get-FileHash -ErrorAction SilentlyContinue |
Sort-Object Path | Out-String
if ($signature -ne $current_signature) {
Write-Host 'File change detected: Restarting...'
go run $path
$signature = $current_signature
}
Start-Sleep -Milliseconds 300
}
使用路径参数执行:
.\watcher.ps1 -path 'main.go'
使用后台作业处理长时间运行的进程
当 Go 应用运行 Web 服务器或其他阻塞操作时,监视脚本会卡住。PowerShell 作业可以让这些进程异步运行。
常用作业 Cmdlet
# Start a background job
Start-Job -Name GoServer -ScriptBlock { ... }
# Stop a job
Stop-Job -Name GoServer
# Remove a job
Remove-Job -Name GoServer
# Retrieve job output
Receive-Job -Name GoServer
# List jobs
Get-Job -Name GoServer
带作业管理的高级监视器
下面的脚本将 Go 服务器作为后台作业启动,在文件变化时重启,并在监视器退出时进行清理。
# watcher.ps1 (advanced version)
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
$path
)
Write-Host 'GoWatcher *Press CTRL+C to quit*'
$dirname = "."
$jobname = "GoServer"
$binary = "GoApp"
function Start-ServerJob {
# Remove any existing job with the same name
Get-Job -Name $jobname -ErrorAction SilentlyContinue | Remove-Job -Force
# Start a new job that builds and runs the Go binary
$job = Start-Job -Name $jobname -ScriptBlock {
param($path, $dirname, $binary)
Set-Location $dirname
# Build the binary (adjust as needed for your project)
go build -o "bin/$binary.exe" $path
# Execute the binary
& "./bin/$binary.exe"
} -ArgumentList $path, $dirname, $binary
return $job
}
# Gather all Go source files
$files = Get-ChildItem $dirname -Filter "*.go" -Recurse
# Initial launch
$job = Start-ServerJob
# Initial signature
$signature = $files | Get-FileHash -ErrorAction SilentlyContinue |
Sort-Object Path | Out-String
try {
while ($true) {
$current_signature = $files | Get-FileHash -ErrorAction SilentlyContinue |
Sort-Object Path | Out-String
if ($signature -ne $current_signature) {
Write-Host 'File change detected: Restarting...'
# Restart the server job
$job = Start-ServerJob
$signature = $current_signature
}
Start-Sleep -Milliseconds 300
}
}
finally {
# Clean up the background job
Get-Job -Name $jobname -ErrorAction SilentlyContinue | Remove-Job -Force
# Ensure the binary process is terminated
if (Get-Process -Name $binary -ErrorAction SilentlyContinue) {
Stop-Process -Name $binary -Force
}
}
以相同方式运行高级监视器:
.\watcher.ps1 -path 'main.go'
该脚本现在:
- 构建 Go 程序为可执行文件。
- 运行 可执行文件作为后台作业。
- 检测 任意
.go文件的变化。 - 在变化时重启 后台作业。
- 在终止时清理 资源。
结论
PowerShell 的面向对象管道、内置别名以及强大的作业系统,使其成为自动化开发任务(如文件监视和进程管理)的优秀选择。通过利用这些特性,你可以创建轻量、跨平台的工具,而无需依赖外部实用程序。