当前位置: 首页 > 知识库问答 >
问题:

如何使用JNA读取Linux命令的输出

欧博简
2023-03-14

我想在Java使用JNA调用Linux mount命令,并从调用结果填充一个装入点列表,但无法理解接口方法的实际返回类型应该是什么。

如果我使用int,那么它将没有任何错误地打印-1。我认为这是某种错误的迹象。

public class MountTest {

private interface CLibrary extends Library {
    String[] mount();
}

public static void main(String[] args) {
    CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);

    System.out.println(INSTANCE.mount());
}

}

我尝试使用基于以下文档的不同返回类型,但没有任何工作。

默认类型映射

我想我的问题是基于错误的签名

我的库有时会导致VM崩溃:仔细检查导致崩溃的方法的签名,以确保所有参数的大小和类型都合适。要特别小心本机指针变体。另请参阅有关调试结构定义的信息。

有谁能帮我这个忙吗。我应该使用什么返回类型,以便能够访问挂载点列表。

更新:我可以通过如下方式调整代码来运行Linux命令:

public class MountTest {

private interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
    int runCommand(String cmd);
}

public static void main(String[] args) {
    CLibrary.INSTANCE.runCommand("mount");
}

}

现在,问题是,它打印到标准输出。我不知道如何使用JNA从stdout读取结果

共有1个答案

苍阳成
2023-03-14

按装入文档

mount()将source(通常是引用设备的路径名,但也可以是目录或文件的路径名,或虚拟字符串)指定的文件系统附加到target中路径名指定的位置(目录或文件)。

这意味着mountsyscall只是挂载目录,这与mount命令不同。您可能正在查找getmetent,它将列出您的所有文件系统挂载点,一个实现如下:

public interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
    Pointer fopen(String name, String mode);
    Mount.ByReference getmntent(Pointer FILE);
}

public static void main(String[] args) {
    final Pointer mountFile = CLibrary.INSTANCE.fopen("/etc/mtab", "r");
    if (mountFile == null) {
        System.err.println("File not exists: " + mountFile);
        return;
    }
    Mount.ByReference mpoint;
    while ((mpoint = CLibrary.INSTANCE.getmntent(mountFile)) != null) {
        System.out.println(mpoint);
    }

}

public static class Mount extends Structure {
    public String mnt_fsname;
    public String mnt_dir;
    public String mnt_type;
    public String mnt_opts;
    public int mnt_freq;
    public int mnt_passno;

    @Override
    protected List getFieldOrder() {
        List<String> fieds = new ArrayList<>();
        for (final Field f : Mount.class.getDeclaredFields()) {
            if (!f.isSynthetic())
                fieds.add(f.getName());
        }
        return fieds;
    }

    public static class ByReference extends Mount implements Structure.ByReference {
    }
}

OBS:据我所知,您不能从JNA中调用编译程序,只能调用库函数和系统调用,那么就不可能调用mount命令,如果您真的想使用这个命令,那么您可能需要使用runtime.getruntime().exec或类似的命令。

更新

看看这个答案,你可以区分什么是程序,什么是syscall或库函数

 类似资料:
  • Linux的lsblk命令的输出是怎样看的? Q1:这是2个硬盘没有挂载吗还是1个呢,为什么他是树状显示的? Q2:type是不一样的,part的意思是这个盘被分成了2个分区吗? 主要是这个树状图没法搜索,所以问下大家

  • 问题内容: 我有以下代码: 试图从阅读器中读取内容已挂起。我该如何解决?我该如何寻找正在发生的事情? 问题答案: 在等待命令完成的同时,必须连续读取输出。否则,如果命令产生足够的输出以填充输出缓冲区,则该命令将挂起,等待缓冲区被消耗,这将永远不会发生。这样您就陷入僵局。 以下示例在监视命令状态的同时连续读取stdout和stderr。它基于官方的JSch 示例 (仅添加了stderr的阅读)。 如

  • 问题内容: 我试图弄清楚如何从用CreateProcessW创建的过程中读取标准输出/错误。我看了看文档,用谷歌搜索了这个列表,但是我还没有找到好的指针/样本:) 到目前为止,这是我想到的(在Windows上运行良好,这是我的Java代码中的相关代码段): 那么…我该如何获取该过程的输出?任何人都已经做到了,并愿意分享一个样本吗? 谢谢大家的任何帮助。 问题答案: 为了向使用功能创建的进程写入控制

  • 问题内容: 我正在使用Groovy在我的Linux机器上执行命令并返回输出,但是我无法以某种方式使用管道(我认为),或者它可能没有在等待命令完成。 有什么问题或我的代码中缺少什么? 我的调用函数: 文件内容(更新:添加了exitVal println): 我的输出(更新:添加了exitVal值): 注意:我在内部使用。 问题答案: 您不能使用进行管道或重定向。这在Java中不起作用,因此在Groo

  • 问题内容: 望回到发展空间;主要使用Java调用某些本地win32函数(我不希望在.NET中构建)…。 有人可以指向我一个可以使用Java(JNI / JNA / SWIG)从不同的运行窗口中读取标题的地方。假设您知道要尝试挂接到的应用程序在内存空间中的哪个位置。 问题答案: JNA中: 要使用它: 您可能需要为HWND使用适当的结构映射,并允许unicode支持。您可以在JNA网站上找到该信息以

  • 本文向大家介绍如何正确使用Linux命令–du,包括了如何正确使用Linux命令–du的使用技巧和注意事项,需要的朋友参考一下 本文简单介绍了如何使用如何使用Linux命令–du,需要的朋友可以参考一下。 du(disk usage) 功能说明:显示目录或文件的大小。 语  法:du [-abcDhHklmsSx][-L <符号连接>][-X <文件>][–block-size][–exclude