Using sed piped with w command show user with the largest idle time

不问归期 提交于 2019-12-12 01:29:20

问题


the w command produces something like this:

01:19:02 up 53 days, 10:44, 15 users,  load average: 0.00, 0.02, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
higrheht pts/5    c-13-76-207-161. 23:21    2:05   0.07s  0.07s -bash
sgergrgr pts/6    c-97-164-31-14.h 00:54    2.00s  0.04s  0.04s -bash
jwegrgrng pts/14   c-23-71-12-251.h 22:48    8:03   0.07s  0.06s vim s2
hiqrefan pts/18   c-13-31-206-169. 23:19    0.00s  0.01s  0.01s -bash
hqeffran pts/19   c-19-71-206-169. 23:19    1:58m  0.02s  0.02s -bash
aqrgri   pts/20   c-84-6-212-27.hs 23:21    0.00s  0.19s  0.17s -bash

I must get a sed script that prints the user with the longest idle time. But the problem is that w shows the idle time in 3 different formats: 1) in seconds: ending with an 's', 2) mm:ss (not ending with 'm' or 's'), and 3) hh:mm (ending with 'm'). So I need to somehow make a sed script that can work with that and I cannot seem to do it.

My attempt: have 2 variables that will first be set just to find out if the highest idle time is in form 1 or 2 or 3. That part is done. Then based on that I was gonna extract the text in that idle field and compare it with a variable and replace if longer time. But it has a letter at the end! so it can't be compared as a number. It is a string. This is the problem.

BEGIN{view1=0
view3=0
userid=""
idlemax=""}

NR>2{
        if($5 ~ /s$/)
        {
            view2=1
        }

        if($5 ~ /m$/)
        {
          view3= 1
        }

}

回答1:


The idle time is nothing more complicated than the last access time of the TTY device that the user is logged in from. So a simple way of doing this would be to grab all the names of the TTYs people are logged in on and stat them:

who -s | awk '{ print $2 }' | (cd /dev && xargs stat -c '%n %U %X')

On some systems, that will emit errors for login sessions such as X11 sessions which aren't on real ttys.

If you want the age instead of the absolute time, post-process it to subtract it from the current time:

who -s | awk '{ print $2 }' | (cd /dev && xargs stat -c '%n %U %X') |
    awk '{ print $1"\t"$2"\t"'"$(date +%s)"'-$3 }'

Or use perl's -A operator:

who -s | perl -lane 'print "$F[1]\t$F[0]\t" . 86400 * -A "/dev/$F[1]"'

From here




回答2:


Rather than using sed, you can do it with bash:

    #!/bin/bash

    decode_seconds()
    {
        echo "${1%%.*}"
    }

    decode_hrs()
    {
      echo $(( $( decode_pair "${1}") * 60 ))
    }

    decode_pair()
    {
      local value="${1}"
      local right="${value##*:}"
      local left="${value%%:*}"
      echo $(( (left * 60 ) + right ))
    }

    decode_value()
    {
      local value="${1}"
      local units="${2}"

      case "${units}" in 
        seconds) decode_seconds "${value}" ;;
        hours)   decode_hrs "${value}" ;;
        *)       decode_pair "${value}" ;;
      esac
    }

    process_data()
    {
      while read user value units extra ; do 
        echo $(decode_value "${value}" "${units}") "${user}"
      done
    }

    w | awk '{print $1,$5}' \
      | sed \
        -e 's/s$/ seconds/' \
        -e 's/m$/ hours/' \
      | process_data \
      | sort -rn


来源:https://stackoverflow.com/questions/42186106/using-sed-piped-with-w-command-show-user-with-the-largest-idle-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!