Stampa il numero di serie del mio Mac in java usando i comandi Unix

Sto provando a stampare il numero seriale del mio mac [modifica: Apple computer] in un programma java. Conosco il comando Unix

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

che realizza questo compito nel terminale.
Quando ci provo

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

il mio numero di serie non è stampato Invece stampa:

  

Penso che il problema è che terminal.exec() non è destinato a prendere l’intera stringa di comando. C’è qualcosa in java simile all’argomento shell = True in Popen(command, stdout=PIPE, shell=True) di python Popen(command, stdout=PIPE, shell=True) che mi permetterà di passare l’intera stringa di comando?

Vedo due possibilità:

  1. Analizza l’output di ioreg -l usando, ad esempio, Scanner .

  2. Avvolgi il comando in uno script di shell ed exec() :

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

Addendum: come esempio di utilizzo di ProcessBuilder e incorporando un utile suggerimento di Paul Cager , ecco una terza 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(); } } } 

I pipe non sono supportati da Runtime.exec (..) poiché sono una caratteristica delle shell. Invece, dovresti emulare il tubo tu stesso, ad es

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

In alternativa, è ansible eseguire una shell come processo, ad esempio Runtime.exec (“bash”), e interagire con essa leggendo e scrivendo i suoi flussi IO. Interagire con i processi è un po ‘complicato e ha alcuni trucchi e consente di eseguire il comando (vedi commenti)

Per ottenere gli indirizzi MAC tramite Java è ansible utilizzare java.net.NetworkInterface :

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

Se non si conosce il nome (presumo che sia ‘eth0’ su linux) dell’interfaccia di rete, è ansible anche iterare tutte le interfacce di rete usando NetworkInterface.getNetworkInterfaces() .