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 tryString 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:
Parse the output of
ioreg -l
using, say, Scanner.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()
.
精彩评论