如何找到以 root 身份登录的用户?

Ano*_*ony 8 bash

最近,我问“如何列出已登录的用户? ”该命令who非常适合此目的。但是我如何找到谁以 root 身份登录?用户名是“root”吗?

pa4*_*080 8

我假设root帐户未启用(默认情况下sudo -i是这样),因此仅适用于成为root的用户。我的建议是以下脚本,它使用命令who -upgrep -at <tty parsed from who -u>查找执行了命令的user哪个脚本。ttysudo -i

#!/bin/bash
LANG=C who -u | while read -a line; do  # Output the whole line: echo "${line[@]}"
        IS_ROOT="$(pgrep -at "${line[1]}" | grep 'sudo -i')"
        [[ ! -z "${IS_ROOT}" ]] && printf '%-7s ( PID %-6s at %s on TTY %-7s) is ROOT: %s %s\n' "${line[0]}" "${line[5]}" "${line[4]}" "${line[1]}" "$IS_ROOT"
done | sed '/grep sudo -i/d' | sort -k13 -k6
Run Code Online (Sandbox Code Playgroud)

解释:

  • who -u显示使用其会话的 PID 登录的用户。可能LANG=C不是强制性的 - 它被放置以保证具有不同locale设置的机器上的时间/日期格式相同。

  • stdin上有流时,循环whiledo执行命令。

  • 该命令read -a将逐行读取输入流,并将这些行作为数组分配给"variable" $line。我们可以通过一个命令输出的整条生产线:echo "${line[@]}"。所以${line[1]}意味着数组的第二个变量$line(第一个是0)。在当前情况下${line[1]}TTY从输出who -u

  • 这是一个简单的脚本,它将输出一个“表格”,其中包含数组元素及其值之间的关系:

    line=( $(LANG=C who -u | head -1) ); for i in {0..6}; do printf '%-11s' "${line[$i]}"; done; echo; for i in {0..6}; do printf '${line[%s]} ' "$i"; done; echo
    
    guest      tty7       2018-01-03 09:52      old        1847       (:0)
    ${line[0]} ${line[1]} ${line[2]} ${line[3]} ${line[4]} ${line[5]} ${line[6]}
    
    Run Code Online (Sandbox Code Playgroud)
  • 命令的输出pgrep -at "${line[1]}" | grep 'sudo -i'将被签名为$()变量的值$IS_ROOT

  • 该命令pgrep -at "TTY"将输出某些 TTY - option 上所有进程的 PID -t --terminal,该选项-a --list-name将列出 PID 和进程名称。

  • 表达式[[ ! -z "${IS_ROOT}" ]] &&可以这样读:如果[变量"${IS_ROOT}"不为!-zthen &&or else ||

  • printf命令用于格式化输出(参考):

    printf '%s some text %s` "$var1" "$var2"
    
    Run Code Online (Sandbox Code Playgroud)
  • 最后sed '/grep sudo -i/d'将从输出中删除无人参与的行(包含我们的命令grep 'sudo -i'whilesort -k13 -k6并将按列 13 和 6 对输出进行排序。


调用脚本find-root,使其可执行 ( chmod +x find-root) 并执行它。

这是一个简单的输出:

$ ./find-root
spas    ( PID 14035  at 12:54 on TTY pts/20 ) is ROOT: 23518 sudo -i
spas    ( PID 14035  at 12:36 on TTY pts/4  ) is ROOT: 23589 sudo -i
guest   ( PID 23575  at 15:00 on TTY pts/4  ) is ROOT: 23589 sudo -i
guest   ( PID 24321  at 15:30 on TTY tty1   ) is ROOT: 24386 sudo -i
Run Code Online (Sandbox Code Playgroud)

这是(在mutt会话中)脚本如何工作的演示(在其先前版本中):

在此处输入图片说明


将脚本放入其中/usr/local/bin以使其可用作 shell 命令。为此,请将以下行作为单个命令复制并执行:

cat << EOF | sudo tee /usr/local/bin/find-root && sudo chmod +x /usr/local/bin/find-root
#!/bin/bash
LANG=C who -u | while read -a line; do 
        IS_ROOT="\$(pgrep -at "\${line[1]}" | grep 'sudo -i')"
        [[ ! -z "\${IS_ROOT}" ]] && printf '%-7s ( PID %-6s at %s on TTY %-7s) is ROOT: %s %s\n' "\${line[0]}" "\${line[5]}" "\${line[4]}" "\${line[1]}" "\$IS_ROOT"
done | sed '/grep sudo -i/d' | sort -k13 -k6
EOF
Run Code Online (Sandbox Code Playgroud)

解释:

  • cat << EOF除非EOF遇到字符串,否则该命令将输出下一行。请注意\$将转义特殊字符的反斜杠,它将$在 cat 中逐字输出。

  • 此输出将通过管道传输|到将写入文件的命令tee(由 执行sudo)的标准输入/usr/local/bin/find-root

  • 如果前面的命令成功&&suddo chmod +x则将执行该命令。


也可以看看: