Ubuntu: What is the interpretation of `awk -F':' '$2 ~ “\$” {print $1}' /etc/shadow`?


I was using the command to get the list of users logged in my machine but I can't understand the meaning of the command.

awk -F':' '$2 ~ "\$" {print $1}' /etc/shadow  


The command won't output the list of users logged in into the machine; in fact the command will parse /etc/shadow, which has no notion of the users logged in into the machine.

The command will output the list of users who have a password set for their account.

Here's the command breakdown (note that this is referred specifically to MAWK, which is the AWK version installed on Ubuntu, where specifying a pattern enclosed in "" is correct and requires the same escaping required for a pattern enclosed in //, as explained in man mawk):

  • -F':': sets the field separator (correspondent to AWK's internal FS variable) to :; that means that each record's (or line's in this case) fields will be splitted on the : character, and that references such as $1, $2, $3, ... will reference respectively the first colon-delimited string of the current record, the second colon-delimited string of the current record, the third colon-delimited string of the current record, ... .

  • $2 ~ "\$": this is a so called "pattern"; it's a condition which is evaluated each time a record is processed. The condition in this case is: if the second field matches the regex \$ (i.e. if the second field contains the character $), execute the following "action".

  • {print $1}: this is a so called "action"; it's a block of code which is executed each time the previous condition evaluates as TRUE. It prints the first field.


It doesn't show users logged to your machine but user accounts that have a password set. Note that should you be using gawk instead of mawk, "\$" would need to be corrected to be either /\$/ or "\\$".

  • -F: : Use the colon as delimiter
  • $2 ~ /\$/ : does the second field (password) contains a dollar sign
  • print $1 : then print the first field (username)

The fact a user is logged in isn't stored in /etc/shadow.


The meaning of your command was explained well enough twice, but I want to add how you can really list all currently logged in users instead:

There's a special command for that, called who.

It prints a list of logged in users and their states. If you add -a, it also includes system users; adding -u (included in -a) prints also the login process' PID and the idle state.

I simply use it together with the -H option to get some column headlines:

$ who -H  NAME        LINE         TIME             COMMENT  myusername  :0           2016-01-26 08:08 (:0)  myusername  pts/0        2016-01-26 08:16 (:0)  

Note that every terminal you open also gets listed (value in LINE column is pts/?).


kos has already explained who the command you posted works and why it's not useful for finding logged in users. My answer intends to answer the second half of your question - how do you actually find the list of logged in users ? There's actually multiple ways.

Byte commander already mentioned who.

skolodya@ubuntu:$ who  xieerqi  :0           2016-01-26 10:52 (:0)  xieerqi  pts/6        2016-01-26 10:52 (:0)  xieerqi  pts/0        2016-01-26 10:55 (:0)  

There's another command , w , which will show a more detailed list of logged in users. This is very useful if you are working on a server, you can check if a user is logged in from a proper IP address, how much CPU their programs are using up, etc.

skolodya@ubuntu:$ w   10:56:23 up 4 min,  3 users,  load average: 0.49, 0.55, 0.26  USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT  xieerqi  :0       :0               10:52   ?xdm?   1:51   0.33s init --user  xieerqi  pts/6    :0               10:52   30.00s  0.01s  0.01s /bin/mksh  xieerqi  pts/0    :0               10:55    0.00s  0.02s  0.00s w  

On the other hand users will output just list of usernames, one per login, so if I'm logged in in TTY and with two gnome-terminal tabs it will show 3 of my usernames.

skolodya@ubuntu:$ users  xieerqi xieerqi xieerqi  

There is also last command, which shows extended list of logins(including previous). For the currently logged in users it shows still logged in line. Knowing that you could filter out the output of last like so:

skolodya@ubuntu:$ last | awk '/still/'                                           xieerqi  pts/0        :0               Tue Jan 26 10:55   still logged in     xieerqi  pts/6        :0               Tue Jan 26 10:52   still logged in     xieerqi  :0           :0               Tue Jan 26 10:52   still logged in   

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »