把常用的十几条运维命令做成一个 Python 小脚本
把常用的十几条运维命令做成一个 Python 小脚本
最近在服务器上排查问题时发现自己老是在敲同样几条命令:看磁盘、看内存、看端口占用、看某个日志最后几行。每次都要回忆一遍参数,比如 df -h 还好,du 想按大小排序就得想一下是 sort -nr 还是加 -k5。索性写了个 Python 脚本把这些常用操作收进去,一条命令出一个结果,顺手也当练手。
脚本长什么样
其实没什么黑魔法,核心就是用 subprocess.run 包一层,再加一个简单的命令分发:
import subprocess, sys
CMDS = {
"disk": "df -h",
"mem": "free -h",
"port": "ss -tlnp",
"big": "du -ah . --max-depth=1 | sort -rh | head -15",
}
def run(key):
cmd = CMDS.get(key)
if not cmd:
print(f"没有这个命令: {key},可选: {', '.join(CMDS)}")
return
r = subprocess.run(cmd, shell=True, capture_output=True, text=True)
print(r.stdout or r.stderr)
if __name__ == "__main__":
run(sys.argv[1] if len(sys.argv) > 1 else "")
用法就是 python ops.py disk、python ops.py big 这样。
过程中遇到的两个小问题
一个是 capture_output 和实时输出的问题。 有一类命令比如 ping 或者长时间的同步任务,我想边跑边看输出,用 capture_output=True 就只能等它跑完才一次性拿到。查了下文档,这种场景要用 Popen 逐行读,或者干脆不捕获输出让它直接打到终端。我最后是给 run() 加了个 live=True 参数,两种模式分开处理:
if live:
subprocess.run(cmd, shell=True) # 不捕获,直接透传
else:
r = subprocess.run(cmd, shell=True, capture_output=True, text=True)
另一个是 shell=True 的注入顾虑。 因为 key 是我自己输的,命令是写死在字典里的,所以没有注入风险。但我一开始手贱把 sys.argv 拼进命令字符串里试了试(比如 ops.py grep xxx 想支持自定义命令),后来想想不对——万一哪天这个脚本被别的自动化工具调用,参数没过滤就是隐患。最后把自定义命令这个功能砍了,只保留白名单,反而用着更踏实。
顺手加的粘性
后来又加了两个很小的功能:du 那条在我的老机器上没有 --max-depth 这个参数(是 macOS 的 BSD 版本),改成 -d 1 才行,为了两台机器都能用我加了个 platform.system() 判断。还有把 CMDS 挪到了一个单独的 ops_config.py,这样改命令不用动主逻辑。
现在的状态是十几条常用命令都收进去了,每天开机先跑一遍 ops.py all(就是把字典遍历一遍)。说实话这脚本没什么技术含量,但这周用它省下来的回忆参数时间,感觉比写它花的时间多,算是赚了。唯一还没想好要不要做的是输出着色——试了下 ANSI 转义码能出颜色,但在 less 管道下会变成乱码,得加个 isatty 判断,下次有兴致再说。
- 点赞
- 收藏
- 关注作者
评论(0)