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
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 signprint $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