Imprimir el número de serie de mi Mac en Java con los comandos de Unix

Estoy intentando imprimir el número de serie de mi mac [editar: computadora Apple] en un progtwig Java. Estoy familiarizado con el comando de Unix

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

que realiza esta tarea en terminal.
Cuando bash

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

mi número de serie no está impreso. En cambio, imprime:

  

Creo que el problema es que terminal.exec() no está destinado a tomar toda la cadena de comandos. ¿Hay algo en Java similar al argumento shell = True en Python’s Popen(command, stdout=PIPE, shell=True) que me permita pasar toda la cadena de comandos?

Veo dos posibilidades:

  1. Analice la salida de ioreg -l usando, por ejemplo, Escáner .

  2. Envuelva el comando en un script de shell y exec() :

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

Adición: como ejemplo de uso de ProcessBuilder , e incorporando una sugerencia útil de Paul Cager , aquí hay una tercera alternativa:

 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(); } } } 

Punts no son compatibles con Runtime.exec (..) ya que son una característica de shells. En cambio, tendrías que emular la tubería tú mismo, por ejemplo

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

Alternativamente, podría ejecutar un shell como un proceso, por ejemplo , Runtime.exec (“bash”), e interactuar con él leyendo y escribiendo sus flujos IO. Sin embargo, interactuar con los procesos es un poco complicado y tiene algunas trampas y deja que ejecute tu comando (ver comentarios)

Para obtener las direcciones MAC a través de Java, puede usar java.net.NetworkInterface :

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

Si no conoce el nombre (supongo que es ‘eth0’ en Linux) de su interfaz de red, puede incluso iterar a través de todas sus interfaces de red usando NetworkInterface.getNetworkInterfaces() .