把 Windows 命令行改成 Linux 的样子
SSH到一台Linux服务器排查慢查询的时候,我一般是这么个节奏:
df -h顺手看一眼磁盘水位,ps aux | grep mysql确认进程状态,tail -f slow.log盯着日志滚。三个命令,闭着眼睛敲,十秒钟摸清情况。
然后关掉SSH窗口,切回Windows桌面干点杂活。打开Windows Terminal,习惯性敲了个 df -h。
"df" 不是内部或外部命令,也不是可运行的程序。
得,又来了。
不是第一次。说实话也不是什么大事,但每次从Linux切回Windows的前几分钟,就是不停地被"命令不存在"打断节奏。我不是不知道PowerShell有自己的一套——Get-Process、Get-ChildItem 这些我背得出来。但肌肉记忆这东西不是你背几个Cmdlet就能覆盖的。在Linux上敲了十来年的快捷键,几个字母就到手了;换成PowerShell,同样的操作你得写一长串,每次还得想一下参数名叫啥。
我有同事选择装WSL。我电脑上也有,但大部分时候我只是想看一眼磁盘空间、搜个进程、跟踪下日志。为了敲三个命令打开一个完整的Linux发行版,感觉像是为了吃一口菜去做一桌饭。
我的需求其实很简单:把PowerShell常用操作的长度缩到能盲打的程度。
其实,我要的只是一份 .bashrc,把它装在PowerShell里。
不对,我连 .bashrc 都不用,我直接写 $PROFILE 就好了。于是花了个把小时,翻文档、试参数、调输出格式,攒了一组函数。后来越加越多,到现在Windows Terminal打开,常用的操作基本不用过脑子。
说几个最常用的。
Get-Diskusage:df -h 的平替
这是我最先写的。DBA嘛,磁盘满了就报警,刻在骨子里的习惯。线上服务器 df -h 一把梭,回到Windows想看下C盘还剩多少——怎么就这么费劲呢?
原始PowerShell写法长这样:
Get-CimInstance -ClassName Win32_LogicalDisk | Select-Object DeviceID, @{N="Size(GB)";E={[math]::Round($_.Size/1GB,2)}}
每次敲都怀疑人生。我把它包了一下:
function Get-Diskusage{ Get-CimInstance -Class Win32_LogicalDisk | Select-Object ` @{Name="Mounted"; Expression={$_.DeviceID}}, @{Name="Size(GB)"; Expression={[math]::Round($_.Size/1GB, 1)}}, @{Name="Used(GB)"; Expression={[math]::Round(($_.Size - $_.FreeSpace)/1GB, 1)}}, @{Name="Avail(GB)"; Expression={[math]::Round($_.FreeSpace/1GB, 1)}}, @{Name="Use%"; Expression={ if($_.Size -gt 0) { "{0:P0}" -f (($_.Size - $_.FreeSpace)/$_.Size) } else { "0%" } } } | Format-Table -AutoSize}
现在敲 Get-Diskusage,输出长这样——跟 df -h 不能说一模一样,至少看着顺眼了:
Mounted Size(GB) Used(GB) Avail(GB) Use%C: 237.0 68.1 168.9 29%D: 931.0 412.5 518.5 44%
lt:按时间排个序
排查问题经常要看哪些文件最新改过。Linux下 ls -lhtr 四个键,PowerShell下 Get-ChildItem | Sort-Object LastWriteTime ... 多敲一个字我都嫌多。
function lt{ Get-ChildItem @args | Sort-Object LastWriteTime}
三行,搞定。顺手再给几个别名:ll 等于 Format-Table 一下,la 等于加 -Force 显示隐藏文件。怎么顺手怎么来。
uptime:看一眼系统跑了多久
DBA 日常巡检三连:系统跑了多久?时间对不对?负载高不高?Linux 上 uptime 一行全告诉你了。PowerShell 里查启动时间得去翻 CIM,每次敲一大串。
function Get-Uptime{ $os = Get-CimInstance -ClassName Win32_OperatingSystem $boot = $os.LastBootUpTime $span = (Get-Date) - $boot Write-Host "Current time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" Write-Host "System uptime: $($span.Days) days $($span.Hours) hours $($span.Minutes) minutes" Write-Host "Last boot: $boot"}
uptime 敲一下,时间和运行时长都有了,巡检脚本里也能直接用。
psg:搜个进程
ps aux | grep 每天高频操作。虽然 Get-Process 本身支持通配符,但包一下敲起来更顺手:
function psg($name){ Get-Process | Where-Object { $_.ProcessName -like "*$name*" }}
psg mysql 就行了。查个 Tomcat、Nginx 什么的也方便。
再搭一个杀进程的:
function kill-port($port){ $conn = Get-NetTCPConnection -LocalPort $port -ErrorAction SilentlyContinue if ($conn) { Stop-Process -Id $conn.OwningProcess -Force Write-Host "Killed process on port $port" } else { Write-Host "No process found on port $port" }}
kill-port 3000,端口被占时救命的。
Get-DirSize:到底谁在吃磁盘
du -sh * 一下就知道哪个目录是磁盘杀手。Windows 上虽然能看到文件夹属性,但要在命令行里快速查一下:
function Get-DirSize{ Get-ChildItem -Directory | ForEach-Object { $size = (Get-ChildItem -Recurse $_.FullName -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum [PSCustomObject]@{ Name = $_.Name SizeMB = [math]::Round($size / 1MB, 2) } } | Sort-Object SizeMB -Descending | Format-Table -AutoSize}
watch:定期看一眼
监控场景下 Linux 的 watch 命令太方便了。watch -n 2 df -h 每两秒刷一次。PowerShell 里搭个循环:
function watch($cmd, [int]$interval = 2){ while ($true) { Clear-Host Invoke-Expression $cmd Start-Sleep -Seconds $interval }}
watch "Get-Diskusage" 或者 watch "psg mysql",跟 watch 一个用法。
这些函数没一个复杂的,最长的也就十几行。但每天在用,一年下来省下的不光是敲键盘的时间,更是一种"不用切换思维模式"的流畅感。
我习惯把它们全放在 $PROFILE 文件里。PowerShell 的 $PROFILE 相当于 Linux 的 .bashrc,每次打开终端自动加载。不知道在哪的话敲一下 echo $PROFILE 就知道了,没有文件就自己建一个。
对了,写完我才发现,我忘了一个最基础的:cls 虽然能用,但跟 clear 比总觉得少了点什么。Set-Alias c clear,加上了。
如果你也有常用的 Linux 命令改成了 PowerShell 版本,欢迎留言分享——看看谁的脑洞更大。