Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

io

unix

macos

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?

like image 572
Alex Ramek Avatar asked Apr 21 '11 06:04

Alex Ramek


People also ask

How do I find my Apple serial number from terminal?

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.

How do you change the serial number on a Macbook?

Changing macbook serial number is fairly easy. Simply drag the bin file and click the change SN button.


3 Answers

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();
        }
    }
}
like image 92
trashgod Avatar answered Nov 13 '22 17:11

trashgod


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)

like image 44
sfussenegger Avatar answered Nov 13 '22 16:11

sfussenegger


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().

like image 1
BertNase Avatar answered Nov 13 '22 17:11

BertNase