解析命令的输出以仅显示基于特定列的数据范围的行

解析命令的输出以仅显示基于特定列的数据范围的行

这当然是 rtfm 的一个例子,因为我遇到过很多类似的帖子,但我在试图找到我要找的东西时迷失了方向。我想 awk 或 grep 能够以某种方式提供帮助,我可以使用一些帮助来指明我正确的方向。

我有一个未来的计划,编写一个带有提示的脚本,其他用户可以运行该函数,但首先我想了解为自己工作的基本想法。

我需要用来who -u显示当前登录的用户,然后根据他们空闲的时间,显示他们的userid、空闲时间和pid。

例如,

01sale1  pts/11       2016-10-05 06:39 00:04       14132 (192.168...)
01sale2  pts/16       2016-10-05 06:40 00:07       17902 (192.168...)
01sale3  pts/14       2016-10-05 06:40   .         17779 (192.168...)
01sale5  pts/25       2016-10-05 06:41 00:04       18339 (192.168...)

当每个人都在线时,列表会很长,并且我们遇到了达到该特定软件的许可证限制的问题。在这个问题得到解决之前,我需要让用户闲置一个小时左右。

我想要的是运行 who -u 来根据第 6 列是否超过一个小时来仅显示第 1、5 和 6 列,因此它会显示 01:** 或以上。

最终,我想制作一个脚本,没有 root 权限的用户可以运行该脚本来向他们显示此信息,然后杀死空闲用户。我不确定我是否想要完全自动化。

我在较旧的 Red Hat 上运行此应用程序

答案1

你可以尝试这样的事情:

who -u | \
awk '$5 ~ /^[0-9][1-9]:.*$|^[1-9][0-9]:.*$/ {printf "%s %s %s\n", $1,$5,$6}'  

awk匹配以 开头的模式0[1-9] || [1-9][0-9]
你可以尝试匹配模式没有开始如果00你愿意的话。

答案2

空闲时间是从 tty 设备的上次访问时间得出的,所以你可以这样做:

kill_idle() (
  sig=$1
  old_ttys=$(find /dev/pts -type c ! -name ptmx -amin +60 -printf %p,)
  [ "$#" -eq 0 ] || pkill "-$sig" -t "$old_ttys"
)
kill_idle HUP; sleep 3; kill_idle KILL

终止所有由这些非活动 tty 控制的进程。

现在,正如 @rudimeter 正确指出的那样,/dev/pts设备并不总是仅用于用户终端会话,因此我们最终可能会终止使用伪终端用于其他目的的进程(例如使用其他终端规则的expect,socat或 pty )。

像终端模拟器、getty、screen、sshd 之类的东西会注册它们在数据库中生成的伪终端,utmp这就是who -u查询的内容。

为了得到闲置的who -u相反,您可以执行以下操作:

old_ttys=$(
  who -u | awk '$5 != "." && $5 !~ /^00/ {printf "%s,", $2}'
)

但请注意,在用于注册 pty 的系统上, 的输出who -u可能会被篡改。utempter

例如,这里使用socat创建 pty:

name=$':0)\nnobody pts/2 2016-10-05 00:00 old 123 (:0' socat pty \
  system:'/usr/lib/x86_64-linux-gnu/utempter/utempter add \"$name\"; sleep infinity',nofork &

utempter是一个 sgid 命令,用于在 utmp 中添加条目。它确实在某种程度上验证了它的输入,因为它的 stdin 必须指向ptmx并且相应的从属点必须由调用者拥有,但它不会验证主持人场地。这里通过指定一个主持人字段中包含换行符,我们在输出中创建一个假条目who -u

nobody pts/2 2016-10-05 00:00 old 123 (:0)

这意味着可以让你杀死任何点上的进程。


仅列出空闲终端:

who -u | awk '$5 != "." && $5 !~ /^00/'

或者只是列出终端控制进程的用户、空闲时间和pid:

who -u | awk '
  $5 != "." && $5 !~ /^00/ {printf "%-16s %6s %d\n", $1, $5, $6}'

w命令可能会为您提供更有用的输出(它也不容易受到上述漏洞的攻击):

$ w -sf | awk 'NR > 2 && $3 !~ /[0-9]s?$/'
stephane tty7      50days /usr/bin/lxsession -s LXDE -e LXDE
stephane pts/1      3:07m /bin/zsh
stephane pts/3      1:25m elinks

相关内容