开发者

Printing my Mac's serial number in java using Unix commands

I am trying to print my mac's [edit: Apple computer] serial number in a java program. I am familiar with the Unix command

ioreg -l | awk '/IOPlatformSerialNumber/ { print $4;}'

which accomplishes this task in terminal.

When I try

String command = "ioreg -l | awk '/IOPlatformSerialNumber/ { print $4; }'"
Runtime terminal = Runtime.getRuntime(); 
String input = new BufferedReader(
    new InputStreamReader(
        terminal.exec(commands).getInputStream())).readLine();
System.out.println(new BufferedReader(
    new InputStreamReader(
        terminal.exec(command, args).getInputStream())).readLine());

my serial number is not printed. Instead it prints:

<+-o Root class IORegistryEntry, id 0x100000100, retain 10>  

I think the problem is that terminal.exec() is not meant to take the whole command string. Is there something in java similar to the argument shell = True in python's Popen(command, stdout=PIPE, shell=True) that will allow 开发者_如何转开发me to pass the whole command string?


I see two possibilities:

  1. Parse the output of ioreg -l using, say, Scanner.

  2. Wrap the command in a shell script and exec() it:

#!/bin/sh
ioreg -l | awk '/IOPlatformSerialNumber/ { print $4;}'

Addendum: As an example of using ProcessBuilder, and incorporating a helpful suggestion by Paul Cager, here's a third alternative:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class PBTest {

    public static void main(String[] args) {
        ProcessBuilder pb = new ProcessBuilder("bash", "-c",
            "ioreg -l | awk '/IOPlatformSerialNumber/ { print $4;}'");
        pb.redirectErrorStream(true);
        try {
            Process p = pb.start();
            String s;
            // read from the process's combined stdout & stderr
            BufferedReader stdout = new BufferedReader(
                new InputStreamReader(p.getInputStream()));
            while ((s = stdout.readLine()) != null) {
                System.out.println(s);
            }
            System.out.println("Exit value: " + p.waitFor());
            p.getInputStream().close();
            p.getOutputStream().close();
            p.getErrorStream().close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}


Pipes aren't supported by Runtime.exec(..) since they are a feature of shells. Instead, you'd have to emulate the pipe yourself, e.g.

String ioreg = toString(Runtime.exec("ioreg -l ").getInputStream());

Process awk = Runtime.exec("awk '/IOPlatformSerialNumber/ { print $4;}'");
write(awk.getOutputStream(), ioreg);

String input = new BufferedReader(new InputStreamReader(awk.getInputStream())).readLine();

Alternatively, you could of course run a shell as a process, e.g. Runtime.exec("bash"), and interact with it by reading and writing its IO streams. Interacting with processes is a bit tricky though and has some gotchas and let it execute your command (see comments)


To get the MAC addres via Java you can use java.net.NetworkInterface:

NetworkInterface.getByName("xxx").getHardwareAddress()

If you don't know the name (I assume it to be 'eth0' on linux) of your network interface, you can even iterate throug all of your network interfaces using NetworkInterface.getNetworkInterfaces().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜