如何在不使用命令的情况下以编程方式关闭/重启 linux 机器(运行时)
Posted
技术标签:
【中文标题】如何在不使用命令的情况下以编程方式关闭/重启 linux 机器(运行时)【英文标题】:How to shutdown/reboot linux machine programatically without using commands(Runtime) 【发布时间】:2017-03-14 02:17:28 【问题描述】:在 Windows 中,可以通过 Java 程序通过本地 (JNA) 调用 Windows API 中的 ExitWindowsEx 函数来关闭机器。我在linux中寻找类似的东西。我知道这可以通过执行命令来完成,但是我不能依赖解析人类可读的文本。
IPC(DBus) 是唯一的方法,还是可以本地加载一些库并本地调用关闭方法。如果有更简单的方法,请告诉我。
Using JNA or similar to shutdown and restart computer in linux and mac
我之前看过这个问题,但它没有提供有关如何以编程方式执行此操作的答案。
【问题讨论】:
看看busyboxhalt.c
你可以使用 SSH 吗?这可能是您将获得的最佳人类可读解析。它会给你一切,直到关机的那一刻。有很多种口味:Python、Java、C#
@ThisClark 我正在尝试自动管理我的服务器。该程序存在,因此我不必登录。我将通过 java 套接字发送命令来关闭机器。我有一个桌面应用程序连接到我发送命令的套接字。
【参考方案1】:
你的程序不能只调用sh
并执行关机命令吗?像那样(需要root):
system("shutdown");
或者如果是桌面会话:
system("dbus-send --system --print-reply --dest=org.freedesktop.login1 /org/freedesktop/login1 "org.freedesktop.login1.Manager.PowerOff" boolean:true");
或者您可以改为包含一个 DBus 连接器库并进行适当的 IPC 调用。
【讨论】:
是否有提供我可以通过 dbus 访问的各种功能的文档? DBus 是一种调用机制。可访问的内容取决于安装的服务。我通常通过d-feet
dbus GUI 浏览器程序(或gdbus introspect
,如果在命令行中)查看可用的内容,然后找出对象对应的服务。服务在某处有他们的文档(如freedesktop.org/wiki/Software/systemd/logind)。 DBus 中的每个类都由一个 xml 文件定义(login1
为“org.freedesktop.login1.xml”)。编程语言的绑定是从这些 xml 文件中生成的(就像在 SOAP 中一样)。
不幸的是,我找不到能够与 DBus 连接的准备就绪的 Java 库。也许在我的产品 SDLC 的下一次迭代中,我将在现有 DBus 库的基础上构建它以使其正常工作。设法通过 POSIX 找到解决方案。【参考方案2】:
所以我在网上做了一些研究后自己设法找到了解决方案。有一个名为 JNA(Java Native Access)的库,可让您本地加载库并解析和依赖关系。使用 JNA,我通过接口在 java 上加载了 POSIX 库。以 sudo 运行代码将让您关闭或重新启动机器。这是代码。
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.ptr.IntByReference;
public interface CLibrary extends Library
public CLibrary INSTANCE = (CLibrary) Native.loadLibrary(Platform.isWindows()?"msvcrt":"c",CLibrary.class);
int kill(long pid, int sig);
int reboot(int magic, int magic2, int cmd, IntByReference arg);
int reboot(int cmd);
int LINUX_REBOOT_MAGIC1 = 0xfee1dead;
int LINUX_REBOOT_MAGIC2 = 672274793;
int LINUX_REBOOT_MAGIC2A = 85072278;
int LINUX_REBOOT_MAGIC2B = 369367448;
int LINUX_REBOOT_MAGIC2C = 537993216;
int LINUX_REBOOT_CMD_RESTART = 0x01234567;
int LINUX_REBOOT_CMD_HALT = 0xCDEF0123;
int LINUX_REBOOT_CMD_CAD_ON =0x89ABCDEF;
int LINUX_REBOOT_CMD_CAD_OFF = 0x00000000;
int LINUX_REBOOT_CMD_POWER_OFF = 0x4321FEDC;
int LINUX_REBOOT_CMD_RESTART2 = 0xA1B2C3D4;
int LINUX_REBOOT_CMD_SW_SUSPEND = 0xD000FCE2;
int LINUX_REBOOT_CMD_KEXEC = 0x45584543;
p s v main()
CLibrary.INSTANCE.reboot(Clibrary.LINUX_REBOOT_CMD_POWER_OFF);
注意:这仅适用于 Linux,不适用于 Windows。要以编程方式关闭机器,请查找ExitWindowsEx。内置于 JNA 库中。
所有C POSIX头文件都可以找到C POSIX Library - Wikipedia
【讨论】:
以上是关于如何在不使用命令的情况下以编程方式关闭/重启 linux 机器(运行时)的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 UINavigationController 的情况下以编程方式进入 rootViewController
如何在不使用外部主机的情况下以编程方式查找设备的外部 IP 地址?
如何在不使用第三方的情况下以编程方式从 Chase 下载我的银行交易?
如何在不使用 HTML 表单的情况下以编程方式将 POST 请求发送到 JSF 页面?