Welcome to bytebang » The blog about all and nothing » Read /etc/passwd with Java8 streams

Read /etc/passwd with Java8 streams

Mar 13 2017

The Problem

As a programmer I am always searching for elegant ways how to accomplish certain things. One of the last tasks was to parse the /etc/passwd file of a linux box. Of course there are multiple ways how to do this, but the Java8 way seems to be a cool solution.

The Solution

The Program consists of two classes. The first one is the 'PwdUser' class which represents one single entry in the passwd file:

public class PwdUser
{
public String userid;
public String password;
public Integer uid;
public Integer gid;
public String fullname;
public String homedir;
public String shell;

public PwdUser(String pwdline)
{
  String[] values = pwdline.split(":");
 
 if(values.length != 7)
 {
  throw new IllegalArgumentException("Line must have 7 fields");
 }
 
 this.userid = values[0];
 this.password = values[1];
 this.uid= Integer.parseInt(values[2]);
 this.gid= Integer.parseInt(values[3]);
 this.fullname = values[4];
 this.homedir = values[5];
 this.shell = values[6];
 
}
}

As you see - you can call the constructor with a full line from the passwd file ant the line is slitted up into separate variables. (Errorchecking could be better - but this example is more for educational purposes)

The second class is the main class:

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test
{

public static void main(String[] args)
{
 // Read the file
 try (Stream<String> stream = Files.lines(Paths.get("/etc/passwd")))
 {
  // Yeah - Java8 read, filter and instantiante on one line of code !
  ArrayList<PwdUser> users = stream.map(PwdUser::new)
    .filter(u -> !u.shell.equals("/bin/false"))
    .filter(u -> !u.shell.equals("/usr/sbin/nologin"))
    .collect(Collectors.toCollection(ArrayList::new));

  // Do something with your users ...
  for (PwdUser u : users)
  {
    System.out.println(u.userid);
  }
 }
 catch (Exception e)
 {
   e.printStackTrace();
 }

}
}

This is where the magic happens:

  1. The file is opened within the try - which means that the JVM closes it automatically (try-with-ressources)
  2. Within the try block we have the stream of the file which is processed as follows:
    1. Create a PwdUser for every line in the file
    2. Remove all objects which are not allowed to log into the system (This is indicated by a shell does not equal to /bin/false and also not to /usr/sbin/nologin
    3. Grab the remeaning ones an put them into a new ArrayList
  3. Iterate over the ArrayList and process the objects

Neat - isn't it ?

Get Social


(c) 2024, by bytebang e.U. - Impressum - Datenschutz / Nutzungsbedingungen
-