I have a simple one-column list of users. It comes from the lastlog command. I need to be able to tell if these accounts are disabled and I do not have root access. I can only view with more and execute the lastlog command. I need to see if users that havent logged in within the last 90 days are still active.

So far I execute

sudo lastlog -b 90

Which gives me the users that logged in..in the last 90 days. Now I just run it through awk printing the first field and that is my simple user list. Now Id like to basically see if in /etc/passwd, their shell is /bin/bash and if in /etc/shadow, there is a ! in their line. How can I do this. I tried for loops and while loops and cant seem to get it right? Any help would be appreciated.

  • can you clarify what output you're looking to get exactly? That would be helpful when writing a script. Also, can you even read /etc/shadow without root access? Sep 4 '14 at 9:53
  • yes i have access to the more command as root and also grep as root. I think I found what I was looking for using grep -f users /etc/passwd (actually /etc/passwd had to be formatted to grep only /bin/bash out of it since I only want active users from that so I redirected it to another file). So in the end it was grep -f users bash_users. Does that sound right?
    – unixpipe
    Sep 4 '14 at 15:41
  • see the answer for my approach. hope that helps. Sep 6 '14 at 13:24

I am not sure if I understand you properly. Is that what you are after?

lastlog -b 90 | awk '{if (NR > 1) print $1 }' | grep -f - /etc/passwd | grep "/bin/bash$"

Here's the breakdown:

  • awk '{if (NR > 1) print $1 }' - print the first column skipping the first line (lastlog's header)
  • grep -f - /etc/passwd - use the standard input as a file to obtain patterns from and search for patterns in /etc/passwd
  • grep "/bin/bash$" - grep for /bin/bash , $ means EOL.

A few notes:

  • lastlog -b 90 - that gives you records older than 90 days. If you want users that logged in within the last 90 days use lastlog -t 90.
  • I only went with (NR > 1) solution because we're using awk anyway. More succinct way of skipping the first line of a file would be sed 1d.


You can use a similar idiom if you also want to filter out the records with ! from /etc/shadow. So the complete command would be:

lastlog -b 90 | awk '{if (NR > 1) print $1 }' | grep -f - /etc/passwd | grep "/bin/bash$" | cut -d ':' -f 1 | grep -f - /etc/shadow | grep -v ":\!:"
  • cut -d':' -f 1 splits the line using : as a delimiter and returns the first field
  • grep -v means invert match (select non-matching lines).

The exclamation point as you have noticed needs to be 'escaped out' -- try entering searches for it with a backslash first: \! instead of ! so it doesn't execute it like a command instead of being treated as text. You could also in many cases quote it with single quotes (not double) like so: '!' -- depending on the command you choose one of those should do it for you.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.