有人告诉我,可以将要关闭的机器分组在一起,并且可以使用shutdown
bash 中的标准命令将它们关闭。
如何进行设置呢?
答案1
假设您在所有有问题的计算机上都设置了 ssh 访问权限,例如
while read host; do
ssh "root@$host" shutdown -h now &
done < host-list
应该管用。如果您需要可配置,只需将主机列表放入类似配置的文件中即可。
答案2
首先,回答你的问题,shutdown
它本身就是一个本地函数。它没有集群的概念。它不知道如何通过您的网络发送消息。可能有点令人困惑的是,它使用该wall
命令告诉所有用户计算机将要关闭。但这只是当前连接到该计算机的用户。并非网络上的所有用户(同样,wall
是本地命令)。
就我而言,我在 LAN 上使用嵌入式软件,其中系统有一个控制器和 N 个服务计算机(在我的测试中为 9 个)。控制器需要具有关闭整个系统的关闭功能,而 ssh 或关闭在这种环境中并不是那么好。
相反,我所做的是创建一个可以自行运行关闭的命令。这非常简单,只需一个非常小的 C 二进制文件:
int main()
{
setuid(0);
system("shutdown -t now"); // adapt the command to what you like
}
您可以使用以下命令进行编译:
gcc -o my-shutdown my-shutdown.c
然后你将它安装在某个地方,例如/usr/sbin
cp my-shutdown /usr/sbin
chown root:root /usr/sbin/my-shutdown
chmod 4755 /usr/sbin/my-shutdown
现在您有了一个可以从任何用户运行的命令,该命令将关闭您的远程计算机。
重要的提示:当然,这在公共系统上不太安全。它对我有用,因为我有一种嵌入式系统。同时,关机不会损坏您的计算机。但它可能会破坏功能。
接下来,我们希望能够从另一台计算机触发该命令。这要求我们有一个在每台服务计算机上运行并侦听连接的服务器。如果您的系统上已经运行了这样的程序,那么只需添加对消息的支持并运行上面的 C 二进制文件应该很容易。然后它将运行关闭命令。
下面我有一个用 NodeJS 编写的非常简单的 TCP 服务器,它可能不适合您的情况,但如果您的服务计算机上尚未运行此类服务,它可以为您提供基本的想法。
实际上,如果您可以用 C 语言编写它,那么它可以包含在我上面展示的工具中(即将命令行更改为以 root 身份运行的服务器,那么您甚至不需要函数setuid()
调用)。
#!/usr/bin/env node
var net = require('net')
var runner = require('child_process')
var server = net.createServer((c) => {
console.log('client connected')
c.on('end', () => {
console.log('client disconnected')
});
c.write('SHUTTING DOWN\r\n')
// this could also directly be the `shutdown -t now` command
// (assuming we run this service as root)
runner.exec("/usr/sbin/my-shutdown")
c.destroy()
})
server.on('error', (err) => {
throw err
})
server.listen(2001, '10.0.2.10', (err) => {
if(err) {
console.log(`can not start listening on port: 1234, ${err}`)
return
}
console.log('server listening on 10.0.2.10:2001');
})
最后,您可以使用 systemd 启动这个 NodeJS 进程。假设您调用它/usr/sbin/my-shutdown-server
,然后编写一个配置文件,例如:
[Unit]
Description=My Shutdown Daemon
[Service]
Type=simple
ExecStart=/usr/sbin/my-shutdown-server
ExecStop=/bin/kill "$MAINPID"
Restart=on-failure
[Install]
WantedBy=multi-user.target
注意:默认情况下,该服务以 root 身份运行。和
User=
可Group=
用于将其更改为另一个用户。
/lib/systemd/system/
使用以下名称保存此文件my-shutdown-server
,现在您可以启用并启动它:
sudo systemctl enable my-shutdown-server
sudo systemctl start my-shutdown-server
从您的控制器,您可以测试发送消息(在本例中,仅连接就足以触发关闭!),例如nc
:
nc 10.0.2.10 2001
您应该会收到一条回复消息:“关闭”并且计算机应该关闭。除非您在关闭之前至少有一个小暂停(即 5 秒而不是“现在”),否则回复消息可能永远不会成功。
再说一次,这里的安全是不存在的。任何可以访问这些计算机的人都可以将其关闭。通过增强服务器,您可以发送任何类型的命令,而不仅仅是关闭(即重新启动、重新启动您的应用程序。无需重新启动等)