Linux shell 自动化运维脚本示例

8次阅读

安全读密码需避免明文暴露:用 read -s 读取后通过 stdin 传递(如 echo “$pass” | sshpass -f -),或用 sshpass -e sshpass 配合临时环境变量并及时 unset;禁用硬编码。

Linux shell 自动化运维脚本示例

怎么让 shell 脚本安全地读取密码而不暴露在 ps 或 history

直接用 read password 或把密码写进变量再传给 ssh/curl,进程列表里一眼就能看到明文——ps aux | grep curl 会漏出整个命令行。这不是“可能被看到”,是默认就会被看到。

  • read -s -p "Password: " password 屏蔽回显,且别把 $password 拼进命令行字符串;改用 stdin 传入,比如 echo "$password" | sshpass -f - ssh user@host
  • 更稳的做法是彻底绕过变量:用 sshpass -e SSHPASS ssh user@host,然后执行前临时设环境变量 SSHPASS="xxx",并确保脚本退出后立即 unset SSHPASS
  • 别把密码硬编码在脚本里,哪怕加了 chmod 600 ——运维脚本常被 catgrepansible 拉取,权限拦不住读操作

判断远程主机是否存活,为什么不能只靠 ping

ping 返回 0 只说明 ICMP 通,但防火墙常禁 ICMP,而 SSH 端口(22)或 http(80/443)开着才是真可用。反过来,ping 通却连不上 SSH 的情况太常见。

  • timeout 3 bash -c 'echo > /dev/tcp/$host/22' 2>/dev/NULL 测试 TCP 连通性,比 nc -z 更少依赖外部命令
  • 如果目标必须走 SSH 才算“活”,直接跑 timeout 5 ssh -o ConnectTimeout=3 -o BatchMode=yes user@$host trueBatchMode=yes 防止卡在密码提示
  • 注意 /dev/tcp/ 是 bash 内置功能,dash/sh 不支持;用 bash -c '...' 显式调用,别只写 #!/bin/sh

日志文件自动轮转但不丢数据,logrotate 常见错在哪

直接配 rotate 7 + daily,结果 crond 触发时旧日志正被 tail -f 或应用持续写入,一转就丢最后几秒内容——logrotate 默认是先 mv 再 kill -USR1,中间有窗口期。

  • 必须加 copytruncate:先拷贝再清空原文件,避免应用因文件句柄失效中断写入
  • 如果应用支持重载信号(如 nginxreload、rsyslog 的 kill -HUP),优先用 postrotate 发信号,比 copytruncate 更精确
  • 别信 dateext 默认格式——%Y%m%d 在跨年时可能和旧文件冲突,显式写成 dateformat -%Y%m%d-%s 避免重复名

find 清理临时文件,为什么 -mtime +7 总是删错

-mtime 看的是“修改时间距今多少个完整 24 小时”,不是“7 天前”。比如文件是昨天 23:59 修改的,今天 00:01 运行 find . -mtime +7,它才过 2 分钟,但已满足“大于 7×24 小时”,会被删掉。

  • 要真正删“7 天前创建/修改”的文件,用 -newermt "7 days ago"gnu find)或 -newerct(创建时间),语义明确
  • 清理 /tmp 下的文件,务必加 -maxdepth 1-type f,否则可能递归/tmp/systemd-private-xxx 这类目录,误删运行中服务的 socket
  • 先加 -print 预览,别一上来就 -delete-delete 自带 -depth,但某些老版本 find 不支持,保险起见还是用 -exec rm {} +

脚本里的时间判断、路径遍历、凭据传递,每个点都卡在“看起来能跑通”和“线上不出问题”之间。差的不是语法,是那半秒没想清楚的执行上下文。

text=ZqhQzanResources