如何使用 JNA 读取 Linux 命令的输出
Posted
技术标签:
【中文标题】如何使用 JNA 读取 Linux 命令的输出【英文标题】:How to read the output of a Linux command using JNA 【发布时间】:2017-10-10 22:53:13 【问题描述】:我想在 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());
我尝试根据以下文档使用不同的返回类型,但没有任何效果。
Default Type Mappings
我认为我的问题是基于
的不正确签名My library sometimes causes a VM crash:仔细检查导致崩溃的方法的签名,以确保所有参数的大小和类型都合适。对本机指针变体要特别小心。另请参阅有关调试结构定义的信息。
谁能帮我解决这个问题。我应该使用什么返回类型才能访问挂载点列表。
更新: 我可以通过如下调整代码来运行 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 从标准输出读取结果
【问题讨论】:
不如直接调用mount函数,使用JNA,看它的返回值(int)判断是否成功:man7.org/linux/man-pages/man2/mount.2.html 我想要的是所有当前附加文件系统的列表,它实际上是已知挂载点的列表。在这种情况下,我不认为返回值会有所帮助 【参考方案1】:由mount 提供文档
mount() 附加由 source 指定的文件系统(通常是 引用设备的路径名,但也可以是设备的路径名 目录或文件,或虚拟字符串)到位置(目录或 文件)由目标中的路径名指定。
这意味着mount
syscall 只是挂载目录,它与the mount command 不同。你可能正在寻找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
或类似的东西。
更新
看看this answer,你可以区分什么是程序,什么是系统调用或库函数
【讨论】:
以上是关于如何使用 JNA 读取 Linux 命令的输出的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用命令的情况下以编程方式关闭/重启 linux 机器(运行时)