👥 w Command - Who is Logged In

Purpose: The w command displays information about currently logged-in users and what they are doing. It shows uptime, load averages, user sessions, login times, idle time, and current processes - providing a comprehensive snapshot of system activity.
Basic Syntax: w [options] [username]

📋 10 Detailed Examples

Example 1: Display All Logged-In Users

Show comprehensive information about all current users:

w

Sample Output:

 15:30:42 up 5 days,  3:25,  3 users,  load average: 0.15, 0.20, 0.18
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
john     pts/0    192.168.1.100    14:20    0.00s  0.12s  0.01s vim document.txt
jane     pts/1    192.168.1.101    15:15    5:00   0.05s  0.05s -bash
root     tty1     -                09:30   45:20   2.50s  0.01s top

Header Information:

Column Meanings:

Example 2: Display Without Header Information

Show only user information, omit the uptime header:

w -h

Sample Output:

john     pts/0    192.168.1.100    14:20    0.00s  0.12s  0.01s vim document.txt
jane     pts/1    192.168.1.101    15:15    5:00   0.05s  0.05s -bash
root     tty1     -                09:30   45:20   2.50s  0.01s top

When to use:

Example script usage:

#!/bin/bash
# Count logged-in users
USER_COUNT=$(w -h | wc -l)
echo "Currently logged in: $USER_COUNT users"

# List usernames only
w -h | awk '{print $1}' | sort -u
Example 3: Show Specific User's Activity

Display information for a particular user:

w john

Sample Output:

 15:30:42 up 5 days,  3:25,  3 users,  load average: 0.15, 0.20, 0.18
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
john     pts/0    192.168.1.100    14:20    0.00s  0.12s  0.01s vim document.txt
john     pts/2    192.168.1.100    15:00    2:15   0.08s  0.03s ssh server.com

Use cases:

Check for multiple sessions:

# Count user's sessions
w -h john | wc -l

# See all activities
w -h john
Example 4: Short Format (Compact Display)

Display abbreviated output without login time, JCPU, or PCPU:

w -s

Sample Output:

 15:30:42 up 5 days,  3:25,  3 users,  load average: 0.15, 0.20, 0.18
USER     TTY      FROM              IDLE WHAT
john     pts/0    192.168.1.100     0.00s vim document.txt
jane     pts/1    192.168.1.101     5:00 -bash
root     tty1     -                45:20 top

Benefits:

Alternative short display:

# Even more compact - username and process only
w -h -s | awk '{print $1, $NF}'
Example 5: Display Without FROM Field

Omit the hostname/IP information:

w -f

Sample Output:

 15:30:42 up 5 days,  3:25,  3 users,  load average: 0.15, 0.20, 0.18
USER     TTY      LOGIN@   IDLE   JCPU   PCPU WHAT
john     pts/0    14:20    0.00s  0.12s  0.01s vim document.txt
jane     pts/1    15:15    5:00   0.05s  0.05s -bash
root     tty1     09:30   45:20   2.50s  0.01s top

Use when:

Example 6: Monitor User Activity in Real-Time

Continuously watch user logins and activity:

watch -n 5 'w -h'

What it does: Updates every 5 seconds, showing current user activity. Press Ctrl+C to stop.

More sophisticated monitoring script:

#!/bin/bash
# user-monitor.sh - Monitor user logins with alerts

ALERT_EMAIL="admin@example.com"
PREVIOUS_USERS=""

while true; do
    CURRENT_USERS=$(w -h | awk '{print $1}' | sort -u | tr '\n' ' ')
    
    # Check for new logins
    for user in $CURRENT_USERS; do
        if ! echo "$PREVIOUS_USERS" | grep -q "$user"; then
            echo "[$(date)] NEW LOGIN: $user"
            
            # Get login details
            w -h | grep "^$user" | while read line; do
                echo "  Details: $line"
            done
            
            # Optional: Send email alert
            # echo "New login: $user" | mail -s "Login Alert" $ALERT_EMAIL
        fi
    done
    
    # Check for logouts
    for user in $PREVIOUS_USERS; do
        if ! echo "$CURRENT_USERS" | grep -q "$user"; then
            echo "[$(date)] LOGOUT: $user"
        fi
    done
    
    PREVIOUS_USERS="$CURRENT_USERS"
    sleep 10
done

Usage:

bash user-monitor.sh
Example 7: Compare with who and whoami Commands

Understand the differences between related commands:

whoami - Shows current user:

whoami
# Output: john

who - Shows logged-in users (simple):

who
# Output:
# john     pts/0        2026-01-25 14:20 (192.168.1.100)
# jane     pts/1        2026-01-25 15:15 (192.168.1.101)

w - Shows users and their activity (detailed):

w
# Output: Full information including processes and CPU time

Comparison table:

Command Shows Detail Level Use Case
whoami Current user Minimal Identify yourself
who All logged-in users Basic See who's logged in
w Users + activity Comprehensive Monitor system usage
Example 8: Security Audit - Detect Suspicious Activity

Monitor for unusual user activity patterns:

#!/bin/bash
# security-audit-w.sh - Detect suspicious user activity

REPORT="/tmp/security_audit_w_$(date +%Y%m%d).txt"

echo "User Activity Security Audit - $(date)" > $REPORT
echo "========================================" >> $REPORT
echo "" >> $REPORT

# 1. Check for users logged in from unexpected locations
echo "=== Remote Logins ===" >> $REPORT
w -h | grep -v "^root" | grep -v "\-$" | \
    awk '{print $1, $3}' >> $REPORT || echo "None" >> $REPORT
echo "" >> $REPORT

# 2. Find idle sessions (potential security risk)
echo "=== Idle Sessions (>30 minutes) ===" >> $REPORT
w -h | awk '$5 ~ /[0-9]+:[0-9]+/ {
    split($5, time, ":");
    if (time[1] >= 30 || length($5) > 5) print $0
}' >> $REPORT || echo "None" >> $REPORT
echo "" >> $REPORT

# 3. Root logins (should be monitored)
echo "=== Root User Activity ===" >> $REPORT
w -h root >> $REPORT 2>/dev/null || echo "No root sessions" >> $REPORT
echo "" >> $REPORT

# 4. Multiple sessions from same user
echo "=== Users with Multiple Sessions ===" >> $REPORT
w -h | awk '{print $1}' | sort | uniq -c | awk '$1>1 {print $0}' \
    >> $REPORT || echo "None" >> $REPORT
echo "" >> $REPORT

# 5. Unusual processes
echo "=== Potentially Suspicious Processes ===" >> $REPORT
w -h | grep -E "(nc|netcat|ncat|/bin/sh|/bin/bash)" | \
    grep -v "^root" >> $REPORT || echo "None" >> $REPORT
echo "" >> $REPORT

# 6. After-hours logins (assuming 9-5 workday)
HOUR=$(date +%H)
if [ $HOUR -lt 9 ] || [ $HOUR -gt 17 ]; then
    echo "=== After-Hours Activity (Current time: $HOUR:00) ===" >> $REPORT
    w -h >> $REPORT
    echo "" >> $REPORT
fi

echo "Audit complete: $REPORT"
cat $REPORT

Run regularly:

# Add to crontab to run every hour
0 * * * * /path/to/security-audit-w.sh
Example 9: Generate User Activity Report

Create detailed activity report for management or audit:

#!/bin/bash
# user-activity-report.sh - Generate comprehensive user activity report

REPORT_FILE="/tmp/user_activity_report_$(date +%Y%m%d_%H%M).txt"

generate_report() {
    echo "======================================"
    echo "USER ACTIVITY REPORT"
    echo "======================================"
    echo "Generated: $(date)"
    echo "Hostname: $(hostname)"
    echo ""
    
    echo "SYSTEM STATUS"
    echo "--------------------------------------"
    w | head -1
    echo ""
    
    echo "CURRENTLY LOGGED IN USERS"
    echo "--------------------------------------"
    TOTAL_USERS=$(w -h | wc -l)
    echo "Total Active Sessions: $TOTAL_USERS"
    echo ""
    
    echo "USER DETAILS"
    echo "--------------------------------------"
    w -h | while read line; do
        USER=$(echo $line | awk '{print $1}')
        TTY=$(echo $line | awk '{print $2}')
        FROM=$(echo $line | awk '{print $3}')
        LOGIN=$(echo $line | awk '{print $4}')
        IDLE=$(echo $line | awk '{print $5}')
        WHAT=$(echo $line | awk '{for(i=8;i<=NF;i++) printf $i" "; print ""}')
        
        echo "User: $USER"
        echo "  Terminal: $TTY"
        echo "  From: $FROM"
        echo "  Logged in at: $LOGIN"
        echo "  Idle time: $IDLE"
        echo "  Current activity: $WHAT"
        echo ""
    done
    
    echo "UNIQUE USERS"
    echo "--------------------------------------"
    w -h | awk '{print $1}' | sort -u | while read user; do
        SESSIONS=$(w -h $user | wc -l)
        echo "$user: $SESSIONS session(s)"
    done
    echo ""
    
    echo "REMOTE CONNECTIONS"
    echo "--------------------------------------"
    w -h | grep -v "\-$" | awk '{print $3}' | sort -u | while read ip; do
        if [ "$ip" != "-" ]; then
            USERS=$(w -h | grep "$ip" | awk '{print $1}' | sort -u | tr '\n' ', ')
            echo "From $ip: $USERS"
        fi
    done
    echo ""
    
    echo "ACTIVITY SUMMARY"
    echo "--------------------------------------"
    echo "Total unique users: $(w -h | awk '{print $1}' | sort -u | wc -l)"
    echo "Remote connections: $(w -h | grep -v "\-$" | grep -v "^USER" | wc -l)"
    echo "Local connections: $(w -h | grep "\-$" | wc -l)"
    echo ""
    
    echo "======================================"
    echo "END OF REPORT"
    echo "======================================"
}

# Generate report
generate_report | tee $REPORT_FILE

echo ""
echo "Report saved to: $REPORT_FILE"

Usage:

bash user-activity-report.sh
Example 10: Advanced Monitoring Dashboard

Create real-time monitoring dashboard:

#!/bin/bash
# user-dashboard.sh - Real-time user activity dashboard

# Colors for terminal
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

print_header() {
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}$1${NC}"
    echo -e "${BLUE}========================================${NC}"
}

while true; do
    clear
    
    print_header "USER ACTIVITY DASHBOARD - $(date '+%Y-%m-%d %H:%M:%S')"
    echo ""
    
    # System info from w header
    echo -e "${GREEN}SYSTEM STATUS:${NC}"
    w | head -1
    echo ""
    
    # Active users count
    ACTIVE=$(w -h | wc -l)
    UNIQUE=$(w -h | awk '{print $1}' | sort -u | wc -l)
    echo -e "${GREEN}ACTIVE SESSIONS:${NC} $ACTIVE   ${GREEN}UNIQUE USERS:${NC} $UNIQUE"
    echo ""
    
    # User activity table
    echo -e "${GREEN}CURRENT ACTIVITY:${NC}"
    printf "%-12s %-10s %-18s %-8s %-s\n" "USER" "TERMINAL" "FROM" "IDLE" "COMMAND"
    echo "----------------------------------------------------------------------"
    w -h | while read line; do
        USER=$(echo $line | awk '{print $1}')
        TTY=$(echo $line | awk '{print $2}')
        FROM=$(echo $line | awk '{print $3}')
        IDLE=$(echo $line | awk '{print $5}')
        WHAT=$(echo $line | awk '{for(i=8;<=NF;i++) printf $i" "; print ""}' | cut -c1-30)
        
        # Highlight root in red
        if [ "$USER" = "root" ]; then
            echo -e "${RED}$(printf "%-12s %-10s %-18s %-8s %-s" $USER $TTY $FROM $IDLE "$WHAT")${NC}"
        else
            printf "%-12s %-10s %-18s %-8s %-s\n" $USER $TTY $FROM $IDLE "$WHAT"
        fi
    done
    echo ""
    
    # Idle session warnings
    echo -e "${YELLOW}IDLE SESSIONS (>30 min):${NC}"
    IDLE_COUNT=0
    w -h | while read line; do
        IDLE=$(echo $line | awk '{print $5}')
        if echo "$IDLE" | grep -q ":"; then
            MINS=$(echo $IDLE | cut -d: -f1)
            if [ "$MINS" -ge 30 ]; then
                USER=$(echo $line | awk '{print $1}')
                echo "  - $USER idle for $IDLE"
                IDLE_COUNT=$((IDLE_COUNT + 1))
            fi
        fi
    done
    if [ $IDLE_COUNT -eq 0 ]; then
        echo "  None"
    fi
    echo ""
    
    # Remote connections
    echo -e "${GREEN}REMOTE CONNECTIONS:${NC}"
    REMOTE=$(w -h | grep -v "\-$" | wc -l)
    if [ $REMOTE -gt 0 ]; then
        w -h | grep -v "\-$" | awk '{print "  -", $1, "from", $3}'
    else
        echo "  None"
    fi
    echo ""
    
    echo "Refreshing in 5 seconds... (Press Ctrl+C to exit)"
    sleep 5
done

Usage:

bash user-dashboard.sh

Features color-coded output, automatic refresh, and highlights important information like root sessions and idle users.

📊 Complete Options Reference

Option Description Example
-h Don't print header (uptime info) w -h
-s Short format (omit login time, JCPU, PCPU) w -s
-f Don't print FROM field w -f
-i Show IP address instead of hostname w -i
-o Old style output (blank IDLE less than 1 minute) w -o
-u Ignore username when computing CPU times w -u
user Show info for specific user only w john

🔍 Understanding w Output

IDLE Time Format

Format Meaning Example
0.00s Active (less than 1 second idle) Currently typing/working
5.00s 5 seconds idle Brief pause
2:15 2 minutes 15 seconds idle Temporarily away
1:30m 1 hour 30 minutes idle Long absence
2days 2 days idle Abandoned session

TTY Types

TTY Type Description
tty1-tty6 Physical console Local terminal (Alt+F1 through Alt+F6)
pts/0 Pseudo-terminal SSH session or terminal emulator
:0 X display Graphical desktop session

Load Average Interpretation

Load average shows system load over 1, 5, and 15 minutes:

Rule of thumb: Load average should be less than number of CPU cores for responsive system.

🎯 Common Use Cases

Quick Checks

# How many users logged in?
w -h | wc -l

# Is specific user logged in?
w john

# What is root doing?
w root

# Get just usernames
w -h | awk '{print $1}' | sort -u

Security Monitoring

# Check for remote logins
w -h | grep -v "\-$"

# Find idle sessions
w -h | awk '$5 ~ /[0-9]+:[0-9]+/'

# Monitor in real-time
watch -n 2 w

System Administration

# Before system maintenance
w  # See who's logged in

# Send message to all users
wall "System maintenance in 10 minutes"

# Check load before starting heavy task
w | head -1

📚 Quick Reference Card

Task Command
Show all users w
Without header w -h
Short format w -s
Specific user w john
Count users w -h | wc -l
List usernames w -h | awk '{print $1}'
Monitor continuously watch w
Related Commands: