![以另一个用户身份从没有 tty stdin 的 root 脚本运行脚本](https://linux22.com/image/586772/%E4%BB%A5%E5%8F%A6%E4%B8%80%E4%B8%AA%E7%94%A8%E6%88%B7%E8%BA%AB%E4%BB%BD%E4%BB%8E%E6%B2%A1%E6%9C%89%20tty%20stdin%20%E7%9A%84%20root%20%E8%84%9A%E6%9C%AC%E8%BF%90%E8%A1%8C%E8%84%9A%E6%9C%AC.png)
使用 CentOs,我想以用户“training”的身份运行一个脚本作为系统服务。我使用 daemontools 来监控该进程,它需要一个以 root 身份运行且没有 tty 标准的启动器脚本。
下面我给出了五次不同的尝试,但均失败了。
:
#!/bin/bash exec >> /var/log/training_service.log 2>&1 setuidgid training training_command
最后一行还不够好,因为对于 training_command,我们需要为训练用户设置环境。
:
su - training -c 'training_command'
看起来像这样(以不同用户身份运行 shell 脚本),但给出 '
standard in must be tty
' 作为 su,确保 tty 存在,以便可能接受密码。我知道我可以通过修改 /etc/sudoers 来让它消失(a lahttps://superuser.com/questions/119376/bash-su-script-giving-an-error-standard-in-must-be-a-tty) 但我不太情愿,而且不确定后果会怎样。:
sudo -u training -i bash -c 'source $HOME/.bashrc; training_command'
同一主题的变奏:'
sudo: sorry, you must have a tty to run sudo
':
runuser - training -c 'training_command'
这给出了
runuser: cannot set groups: Connection refused
。我发现这个错误没有任何意义或解决办法。:
ssh -p100 training@localhost 'source $HOME/.bashrc; training_command'
这更像是一个笑话,用来表达绝望。甚至这个也失败了
Host key verification failed.
(主机密钥在known_hosts中,等等)。
注意:如果我从根 shell 运行包装器脚本,那么 2、3、4 均能正常工作。仅当系统服务监视器(daemontools)启动它时才会出现问题(我猜没有 tty 终端)。
我陷入了困境。这件事真的很难实现吗?
我感谢所有关于最佳实践的见解和指导。
(这也已在超级用户上发布:https://superuser.com/questions/434235/script-calling-script-as-other-user)
答案1
您需要禁用forrequiretty
中的设置。通过添加以下行:/etc/sudoers
root
visudo
Defaults:root !requiretty
您还需要以下行/etc/sudoers
才能root
完成所有操作(这应该默认启用,但请检查以确保):
root ALL=(ALL) ALL
然后您可以执行以下操作:
sudo -u training /path/to/training_command
答案2
这似乎本质上是一个特殊情况这个问题;我们可以用来伪造一个 tty。唯一的问题是,出于某种原因,script -c
我无法直接使用该技巧,而且如果您真的必须在之前进行源代码处理,那么它就有点难看了。尝试:su
sudo
~/.bashrc
training_command
echo password | script -c "sudo su - training -c training_command"
答案3
选择第一个并设置所需的环境变量。
如果您已经使用过 daemontools,那么您就不需要手动创建或处理日志文件了。Daemontools 会为您完成这项工作。
这是应用程序运行脚本
#!/bin/bash
exec 2>&1
exec setuidgid training sh -c 'YOURVARIABLE=yourvalue exec training_command'
然后创建一个log
具有其自己的运行脚本的目录运行脚本。
请参阅此条目来设置日志: http://cr.yp.to/daemontools/faq/create.html#runlog
答案4
在SSH下,你可以foo.sh
以普通用户身份运行命令:
$ ssh [email protected] bash /path/to/foo.sh
如果某个foo.sh
命令需要 root 权限,例如,netstat
,则将其包装在su
命令中,如下所示(替换原始的netstat -tunple
):
su -c "netstat -tunpl" root
foo.sh
并像这样运行:
$ ssh -t [email protected] bash /path/to/foo.sh
这将提示两个密码,第一个是normal_user
,第二个是root
。