xiaowei-system/skills/devops/devops-umbrella/references/sudo-password-pattern.md

3.9 KiB
Raw Blame History

Sudo 密码传递模式

常见陷阱heredoc 消耗密码导致 sudo 认证失败

模式对比

错误heredoc 中使用 echo | sudo -S

# 失败密码在第一个命令后被消耗sudo 第二次读取时得到空行
echo 'z1020' | sudo -S bash -c 'cat > /etc/file << EOF
some content
EOF
another command'   # 这里 sudo 读不到密码

正确:单条命令直接 pipe

echo 'z1020' | sudo -S sysctl -w vm.swappiness=10

正确:多条命令用 bash -c内容不在 heredoc

# bash -c 的参数是单行字符串,不是 heredoc密码可重复使用
echo 'z1020' | sudo -S bash -c 'sysctl -w vm.swappiness=10 && sysctl -w net.core.default_qdisc=fq'

正确:分开执行(最可靠)

# 每条命令独立 pipe密码各用一次
echo 'z1020' | sudo -S sysctl -w vm.swappiness=10
echo 'z1020' | sudo -S sysctl -w net.core.default_qdisc=fq
echo 'z1020' | sudo -S sysctl -w net.ipv4.tcp_congestion_control=bbr

正确:用 tee 写入文件(替代 heredoc

# heredoc 需要交互式 shell用 tee 代替
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swappiness.conf

根本原因

echo 'password' | sudo -S 中,密码通过 stdin 传递,但:

  • Heredoc <<EOF 也会从 stdin 读取内容,把密码吃掉了
  • sudo -S 第一次 read 成功,后续命令重试时 stdin 已耗尽

验证方法

# 检查上条 sudo 命令是否成功
sudo -n true && echo "sudo OK" || echo "sudo failed"

坑 #6sudo flag 顺序打错2026-06-28 实测)

症状:单独跑 echo 'pw' | sudo -S -v 接受密码,但换 echo 'pw' | sudo -S <args> 写法立即 [3 incorrect password attempts]

根因flag 顺序/组合打错(比如 sudo -S -p '' gpg ...)时 sudo wrapper 抛 usage error但 sudo 内部认证层把 stdin 已消耗算成"密码不匹配",导致 3 次 fail 锁。

正确(-S 必须独立)

echo 'z1020' | sudo -S gpg --dearmor -o /usr/share/keyrings/microsoft-edge.gpg /tmp/msedge.asc

教训:先在最小可工作命令验证 sudo 接受密码(echo 'pw' | sudo -S whoami再叠加业务参数。Flag 顺序/组合改一次验证一次。


坑 #7提议"额外步骤"前没先做 preflight浪费 3-4 步)

反例2026-06-28 Edge

  1. 用户问要不要加 apt 自动更新源 → 直接跑到加 GPG key 那里,失败 2 次
  2. 真相:.deb 安装时 post-install hook 早已写好 /usr/share/keyrings/microsoft-edge.gpg/etc/apt/sources.list.d/microsoft-edge.sources,只是我没先看一眼。

正确流程:提议任何"额外配置"前先 fs 探测现状:

ls /etc/apt/sources.list.d/ | grep -i -E 'edge|micros|teams|vscode|...'
ls /usr/share/keyrings/ | grep -i -E 'edge|micros|microsoft|...'
cat /etc/apt/sources.list.d/<name>.list /etc/apt/sources.list.d/<name>.sources 2>/dev/null

规则:先 ls/cat 看现状,再告诉用户"剩什么没做",不要上来就说"我没做 X要不要我加"。

⚠️ 这条规律适用于大部分 .debMicrosoft 系Edge 已验证VS Code/Teams/PowerToys 推测同模式)通常自带 post-install 写源。其他发行包Chrome / Slack / Discord beta通常自带,需要手动加。


坑 #8sudo -v 单独 stamp回避管道 sudo 反复认证

观察echo 'pw' | sudo -S <业务命令> 容易踩 sudo flag 顺序/组合边界问题,反复解锁浪费时间。

解决:先 stamp sudo 缓存(默认 5min之后业务命令直接 sudo <cmd>

# 一次性输密码
echo 'z1020' | sudo -S -v
# 5 分钟内免密(不指定命令)
sudo dpkg -i /tmp/edge.deb
sudo apt update

前提5 分钟窗口期内能列出所有 sudo 操作。如果密集 sudo 命令散落在整个 session 里,就只能在每次登录态新发命令时分别 echo | sudo -S