The output format of w

w command shows who is logged on and what they are doing.

A typical output of w looks like this (the output is generated by copilot)

$ w
 23:02:30 up  1:01,  1 user,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
jason    tty7     :0               22:01    1:01m  1.01s  1.01s /usr/lib/gdm3/gdm-x-session --run-script env GNOME_SHELL_SESSION_MODE=ubuntu /usr/bin/gnome-session --systemd --session=ubuntu

The effect of flags such as -s are well explained in other places, so I will not repeat them here. However, for someone who's interested in parsing the output of w, the following information might be useful. -- you can always refer to the source code but I bet it would be better to have a quick reference here.

TTY

The TTY column shows the terminal name of the terminal the user is logged in on. It is very powerful -- it can distinguish between local terminal and pseudo-terminal, combining the info in FROM it can also distinguish between different pseudo-terminals (details later).

Different types of terminals are represented by different characters:

  • tty: A tty is a native terminal device, the backend is either hardware or kernel emulated.
  • pts: A pty (pseudo terminal device) is a terminal device which is emulated by an other program (example: xterm, screen, or ssh are such programs). A pts is the slave part of a pty. Most of the cases, it means the user is logged in via ssh or screen.
  • :0: A display is managed by a display manager (like gdm, kdm, or xdm). A display is NOT a terminal, but it can spawn terminals on request. (It does not have to be 0, if you have multiple displays, you will see :1, :2 etc.)

The number following pts or tty is the number of the terminal. For example, tty7 is the seventh terminal, pts/0 is the first pseudo-terminal.

FROM

The FROM column shows where the user logged in from. It is a string, and it can be:

  • :0: The user is logged in from a display manager.
  • IP address: The user is logged in from a remote machine via ssh.
  • Starts with :pts/0: Usually means that this is a xterm or screen session.
  • Starts with tmux(114514): Definitely a tmux session.

IDLE, JCPU and PCPU

Their outputs are all foramtted using print_time_ival7 function. I'll use python-like pseudocode to explain.

if idle_time <= 60s:
    output "{seconds}.{centiseconds}s" # e.g. 3.05s
    # first number will not be zero padded, but the second number will be
elif idle_time > 60s and idle_time < 1 hour:
    output "{minutes}:{seconds}" # e.g. 1:03
    # first number will not be zero padded, but the second number will be
elif idle_time >= 1 hour and idle_time < 2days:
    output "{hours}:{minutes}m" # e.g. 1:03m
    # first number will not be zero padded, but the second number will be
elif idle_time >= 2 days:
    output "{days}days" # e.g. 2days

So if you want to parse idle time / JCPU / PCPU, one should first check according to whether the string contains days, m, s or : and then decide how to parse it.

LOGIN@

if current_time - login_time > 12 hours and login_time.day_in_the_year is not today:
    if current_time - login_time > 6 days:
        output "{day}{month}{year}" # e.g. 07Aug23
        # the year is actually calculated by number of years from 1900 modulo 100
    else:
        output "{weekday}{hour}" # Wed08
        # the hour is in 24-hour format
else:
    output "{hour}:{minute}" # 03:02
    # the hour is in 24-hour format
    # both numbers will be zero padded

To parse this, one could possibly use the length of the string to first determine whether it is in day-month-year format (7 in length). If it's 5 in length, then one could check whether it contains : to determine whether it's in hour-minute format or weekday-hour format.