我想在 bash 脚本中以 root 身份运行命令。
该命令需要能够从 STDIN 读取。
我有一个 root 密码作为 bash 脚本中的本地变量,并且不想手动输入它。
当我尝试过:
我知道以 root 身份运行初始脚本的方法(并实际使用它,但寻找更好的生活方式),但当涉及复杂的逻辑、不同的用户和环境变量时,它有其局限性。
我知道 sudo-NOPASSWD 方法,但出于安全原因我不想使用它。
我知道
su -c
方法,但它让我每次都输入 root 密码:
su - -c "adduser new_user"
- 我知道heredoc方法,但它阻止了我的STDIN:
read -sp "Please, enter root password: " ROOT_PASSWD
echo
su - <<EOI
$ROOT_PASSWD
echo "<This password input is handled automatically based on previously asked password>"
# Do NOT asks user password and data as supposed to:
adduser new_user
EOI
答案1
你可以这样做,
echo $PASSWORD | su -c "tac <<_EOF
1
2
3
_EOF"
但正如其他人所回应的那样,这并不安全或不推荐。您的方法不起作用的原因是,当您希望将 stdin 传递给 su 执行的命令时, su 覆盖了整个脚本。另外,大多数 adduser 命令允许您通过命令行而不是标准输入指定密码,所以我不确定您是否需要这样做,只需使用 su 的 -c 选项就足够了。
答案2
将 root 密码保存在任何文件中无异于搬起石头砸自己的脚。风险太高。
最好的方法是为专用任务编写一个脚本,并将其分配给setuid 位权限(例如 chmod4755) 以 root 身份运行,并具有专用于该任务的组的组权限。那个脚本不会将写权限分配给除 root 以外的任何人,root 是脚本所有者。
然后创建一个专用用户 ID 以在专用空间中执行该任务 (例如 cron、sync、daemon、lp、mail、sys 等)。然后让该用户在需要时运行该任务。这种方法使其成为具有执行受限任务的已知特权的配置设施。这是最干净的方法。
sudo 的全部目的是强制进行交互式验证,以确保尝试获得超级用户权限的用户是真实且合法的,因为他们试图“规避”预定义的进程。这并不容易。
似乎 setuid 已被禁用,而没有尝试使用它来标记其非活动状态。 那不是犹太洁食!
演示 setuid 功能的小脚本是不活跃:
#!/bin/sh
BASE=`basename "$0" ".sh" `
TEST="${BASE}.testor"
touch "${TEST}"
该脚本正在运行的快照: