I can not get this to return anything but null
for ip. I must be missing something in the way that I format the operations inside the String array, please help! Also, is there a better sdk for command line work in Java? Update For future reference, this is an EC2 Instance, and doing an InetAddress.getLocalHost() returns null, so I've reverted to the command line (the AWS SDK is kind of a pain just to drill down for a localhost IP).
// Command to be run: /sbin/ifconfig | awk 'NR==2{print$2}' | sed 's/addr://g'
String[] command = new String[] {"/sbin/ifconfig", "awk 'NR==2{print$2}'", "sed 's/addr://g'" };
String ip = runCommand(command);
public static String runCommand(String[] command) {
String ls_str;
Process ls_proc = null;
try {
ls_proc = Runtime.getRuntime().exec(command);
} catch (IOException e1) {
e1.printStackTrace();
}
DataInputStream ls_in = new DataInputStream(ls_proc.getInputStream());
开发者_如何学运维 try {
while ((ls_str = ls_in.readLine()) != null) {
return ls_str;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
- Why do you try to use
Runtime.exec()
when there's a perfectly easy way to enumerate network interfaces in Java? - You try to execute multiple commands, piping one commands output onto the other one. That job is usually done by the shell. By directly executing it, you don't get that feature. You can work around that fact by invoking the shell and passing the whole pipe to it as an argument to be executed.
- Read When
Runtime.exec()
won't. It summarizes all major pitfalls you can fall into when usingRuntime.exec()
(including the one mentioned in #2) and tells you how to avoid/solve them.
StringBuilder result = new StringBuilder()
try {
while ((ls_str = ls_in.readLine()) != null) {
result.append(ls_str);
}
} catch (IOException e) {
e.printStackTrace();
}
return result.toString();
If you pass an array to exec(), it acts as if all the elements after the first are arguments to the first one. "awk" is not a valid argument to ifconfig
.
The form of Runtime.exec()
which takes a String[]
does not execute multiple commands in a pipeline. Rather it executes a single command with additional arguments. I think the easiest way to do what you want is to exec
a shell to do the pipeline:
Runtime.getRuntime().exec(new String[] {
"bash", "-c", "/sbin/ifconfig | awk 'NR==2{print$2}' | sed 's/addr://g'"
});
You can use java.net.NetworkInterface
. Like this:
public static List<String> getIPAdresses() {
List<String> ips = new ArrayList<String>();
try {
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while (e.hasMoreElements()) {
NetworkInterface ni = e.nextElement();
Enumeration<InetAddress> e2 = ni.getInetAddresses();
while (e2.hasMoreElements()) {
InetAddress ip = e2.nextElement();
if (!ip.isLoopbackAddress())
ips.add(ip.getHostAddress());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return ips;
}
Joachim Sauer already posted the link to the documentation
精彩评论