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?
Use a Mac Terminal Command To find your serial number using this method, open Terminal from the Applications folder or typing Terminal in Spotlight. Next, input the following command “system_profiler SPHardwareDataType | grep Serial” and press the Enter key. Your serial number should appear on the succeeding line.
Changing macbook serial number is fairly easy. Simply drag the bin file and click the change SN button.
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()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With