Glam Prestige Journal

Bright entertainment trends with youth appeal.

I want my grep to print a user list from /etc/passwd, and I've studied /etc/login.defs' minmax values for the ones I want my grep to fetch:

# Min/max values for automatic uid selection in useradd
#
UID_MIN 1000
UID_MAX 60000
# System accounts
#SYS_UID_MIN 100
#SYS_UID_MAX 999

Actual user IDs start at 1000 and finish at 60000, and system user IDs start at 100 and finish at 999.

So I made my script look like this (warning spanish text):

2)
echo
echo "LISTA DE USUARIOS"
cat /etc/passwd | grep -E "*:[*-6][0-9][0-9][0-9][0-9]:*" | cut -d":" -f1
echo
echo "LISTA DE USUARIOS DEL SISTEMA"
cat /etc/passwd | grep -E "*:[1-9][0-9][0-9]:*" | cut -d":" -f1
;;

It's obviously plain not working and grep is very hard for me so I'm not sure how to make it work. I tried (and always try) reading others' solutions but I think I'll need this one explained to me if I ever want to learn.

If possible I'm trying to avoid perl territory. I can't handle that much yet though I understand what it's famed for.

Anything else you need to know to help me, let me know.

Thanks! (also, first post ever here)

2

4 Answers

This awk command does what you want. First, you set the record separator to : with FS=":", check if the third element is 1000-60000, and if so, print element 1 (username):

awk 'FS=":" {if ($3 > 999 && $3 < 60001) print $1}' < /etc/passwd
1

Another awk version, with arrays. A bit more lengthy but working

awk -F':' ' $3 >= 1000 && $1 != "nobody" {i++;humanuser[i]=$1 } $3 < 999 { k++;sysuser[k]=$1} END {printf"****HUMAN USERS\n";for (j=1;j<=i;j++) printf humanuser[j]" "; printf "\n*****SYSTEM USERS\n"; for(m=1;m<=k;m++) printf sysuser[m]" "}' /etc/passwd

Sample output:

****HUMAN USERS
xieerqi testuser
*****SYSTEM USERS
root daemon bin sys sync games man lp mail news uucp proxy www-data backup list irc gnats libuuid syslog messagebus usbmux dnsmasq avahi-autoipd kernoops rtkit saned whoopsie speech-dispatcher avahi lightdm colord hplip pulse gdm 
1

You can use grep with Perl Compatible RegEx (PCRE) :

  • To get the usernames with UID >= 1000 :

    grep -Po '^[^:]+(?=:[^:]+:\d{4,})' /etc/passwd
  • To get the usernames with 100 <= UID <= 999 :

    grep -Po '^[^:]+(?=:[^:]+:\d{3})' /etc/passwd

Here -P indicates PCRE, -o indicates we are going to take only the matched portion.

  • ^[^:]+ gets us the username, everything upto first :

  • (?=) is zero width positive lookahead pattern, we are using this to ensure that we match our desired portion after the username

  • :[^:]+: matches :x: and then \d{4,} matches four or more digits (>=1000)

  • On the other hand :[^:]+: matched :x: then \d{3} matches exactly three digits (100 to 999).

DISCLAMER: The following java answer is for educational purposes and the fun of coding only. If you downvote, explain in the comments why.

Code

The code bellow reads each line from /etc/passwd , splits that line into strings with : as separator, and sorts users depending on their UID into appropriate ArrayLists.

package com.askubuntu.users.serg;

import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Scanner;

/** * * A program to sort human and system users from /etc/password * * @author Serg Kolo * */
public class UserList { private static final String SEPARATOR = "============="; private static final int SYS_UID_MAX = 999; private static final int UID_MAX = 1000; private static final String FILENAME_PASSWD = "/etc/passwd"; private static final String COLON = ":"; private static final String NOBODY = "nobody"; /** * * @param args * @throws IOException */ public static void main(String[] args) { File f = new File(FILENAME_PASSWD); try (Scanner readFile = new Scanner(f)) { ArrayList<String> humanUsers = new ArrayList<>(); ArrayList<String> systemUser = new ArrayList<>(); while (readFile.hasNext()) { String[] field = readFile.nextLine().split(COLON); int uid = Integer.parseInt(field[2]); if (uid >= UID_MAX && (!NOBODY.equals(field[0]))) { humanUsers.add(field[0]); } else if (uid <= SYS_UID_MAX) { systemUser.add(field[0]); } } printUsers(humanUsers, "Human Users:"); printUsers(systemUser, "System Users:"); } catch (FileNotFoundException e) { System.err.println(e.getLocalizedMessage()); } } /** * * print users * * @param users * @param header */ private static void printUsers(ArrayList<String> users, String header) { System.out.println(header); System.out.println(SEPARATOR); System.out.println(users); System.out.println(); }
}

Procedure

  1. Save the code above as userlist.java
  2. Compile and run with your preferred Java IDE. If you prefer command line, do

    javac UserList.java && java UserList
  3. Output will appear in the console of your IDE

Sample output

Human Users:
=============
[xieerqi, testuser]
System Users:
=============
[root, daemon, bin, sys, sync, games, man, lp, mail, news, uucp, proxy, www-data, backup, list, irc, gnats, libuuid, syslog, messagebus, usbmux, dnsmasq, avahi-autoipd, kernoops, rtkit, saned, whoopsie, speech-dispatcher, avahi, lightdm, colord, hplip, pulse, gdm, sshd]

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy