如何将bash中的用户空闲会话与以分钟为单位的限制进行比较?

时间:2019-04-29 16:36:02

标签: bash shell

我正在尝试提出一个bash脚本,以检查用户的空闲时间是否超过30分钟,然后终止会话,但我无法提出正确的过滤条件。

who -u | cut -c 1-10,38-50 > /tmp/idle$$

for idleSession in `cat /tmp/idle$$ | awk '{print $3}'`
do

    if [ "$idleSession" -gt 30 ]; then
       echo  $idleSession
    fi
done

我发现了egrep的建议,但我不明白。 我不断得到

user_test.sh: line 6: [: 14:25: integer expression expected

更新:我用错字更新了代码,打印了所有内容,而价值却没有与我的30m限制进行比较

1 个答案:

答案 0 :(得分:1)

Shellshock干净的代码可打印当前计算机上空闲超过30分钟的会话的详细信息:

#! /bin/bash -p

# Check if an idle time string output by 'who -u' represents a long idle time
# (more than 30 minutes)
function is_long_idle_time
{
    local -r idle_time=$1

    [[ $idle_time == old ]] && return 0
    [[ $idle_time == *:* ]] || return 1

    local -r hh=${idle_time%:*}
    local -r mm=${idle_time#*:}
    local -r idle_minutes=$((60*10#$hh + 10#$mm))

    (( idle_minutes > 30 )) && return 0 || return 1
}

who_output=$(LC_ALL=C who -u)

while read -r user tty _ _ _ idle_time pid _ ; do
    if is_long_idle_time "$idle_time" ; then
        printf 'user=%s, tty=%s, idle_time=%s, pid=%s\n' \
            "$user" "$tty" "$idle_time" "$pid"
    fi
done <<<"$who_output"

代码假定LC_ALL=C who -H -u的输出如下:

NAME     LINE         TIME         IDLE          PID COMMENT
username pts/9        Apr 25 18:42 06:44        3366 (:0)
username pts/10       Apr 25 18:42  old         3366 (:0)
username pts/11       Apr 25 18:44   .          3366 (:0)
username pts/12       Apr 25 18:44 00:25        3366 (:0)
...

在您的系统上看起来可能有所不同,在这种情况下,可能需要修改代码。

  • who -u输出的“ idle”字符串可以采用几种不同的形式。有关详情,请参见who (The Open Group Base Specifications Issue 7)。为了使主代码更简单,对它的处理并不简单,可以通过is_long_idle_time函数来完成。
  • 该函数从“ 06:44”之类的空闲字符串中提取小时(hh(06))和分钟(mm(44)),并计算空闲分钟总数({{ 1}}(404))。算术表达式中的基本限定符(idle_minutes)对于防止字符串'08'和'09'被视为无效的八进制数字是必需的。参见Value too great for base (error token is "08")
  • 根据Locale10#输出的格式可以(并且确实)有所不同。使用who -u运行它可以确保无论用户的环境如何,它都将生成相同的输出。参见Explain the effects of export LANG, LC_CTYPE, LC_ALL
  • 在主循环中,您可以获取闲置超过30分钟的所有会话的用户名,终端/线路,空闲时间和PID。但是,使用此信息杀死空闲会话可能并不简单。在某些系统上,多个会话可能与同一PID关联。即使您可以可靠地确定空闲会话的PID,空闲度也可能是错误的。例如,正在运行尚未运行任何终端输出的长期运行程序的会话似乎处于空闲状态。杀死它可能不是一件明智的事情。考虑改用TMOUT。请参阅How can one time out a root shell after a certain period of time?(请注意,它可以用于任何用户,而不仅限于root用户)。