如何在 Linux 中检测通过 GUI 登录的用户

Posted

技术标签:

【中文标题】如何在 Linux 中检测通过 GUI 登录的用户【英文标题】:How to detect a user logged in through GUI in Linux 【发布时间】:2012-07-13 02:43:44 【问题描述】:

我想在我的程序中捕获通过 GUI 登录的用户名。我的程序从 root 登录作为守护进程运行。如果非 root 用户通过 GUI 登录,我的程序应该会收到通知。 我正在粘贴我当前的程序,该程序调用一个 perl 脚本,利用系统调用来检查谁是当前登录的用户。我也在粘贴我的 perl 脚本以供参考。

#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/Xfuncs.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
int main()

    char *user;
    char buf[1024];
    int fd, ret;
    fd = open("/tmp/log", O_TRUNC|O_RDWR|O_CREAT);
    if (!fd) 
        printf("Error opening file\n");
        exit(1);
    
    chmod("/tmp/log", S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP
            | S_IROTH | S_IWOTH | S_IXOTH);
    daemon(0, 0);
    while (1) 
        system("perl /home/curr-usr.pl");
        sleep(5);
     
    return 0;

用于获取当前用户登录的 perl 脚本。

#!/usr/bin/perl
my $result;
$result = `whoami`;
open FH, "+>>", "/tmp/log" or die $!;
print FH "$result ";
close (FH);

在上面的 c 程序中,我每 5 秒在一个 while 循环中调用 perl 脚本。 perl 脚本使用命令“whoami”来让当前用户登录并将其转储到 /tmp/log 文件中。

我想要实现的是,如果 user1 登录 perl 脚本应该给我当前用户是 user1。相反,perl 脚本将我作为当前用户提供 root,而不管我通过 GUI 登录的用户是什么,因为我正在使用 root 用户运行 C 程序和 perl 脚本。

谁能告诉我C程序可以通过GUI了解当前用户登录的机制吗? 非常感谢任何帮助。

【问题讨论】:

我不确定您是否想从 X11 子系统中提取登录信息...为什么不使用 e。 G。一些用于检测用户登录的 Linux API? 我真正想要的是拥有当前登录的 X Window 和用户的映射。当我们在一个用户中连续运行程序时,我们如何使用 Linux API 来检测用户登录,因为我的要求是在我启动程序后让所有用户登录系统。谢谢 【参考方案1】:

您可以像这样使用主显示屏检测用户:

#!/bin/bash

#Detect the name of the display in use
display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"

#Detect the user using such display
user=$(who | grep '('$display')' | awk 'print $1')

#Detect the id of the user
uid=$(id -u $user)

【讨论】:

【参考方案2】:

我正在使用 XFCE4 和 LXDM。 "who" 和 "users" 只报告在终端上登录的用户。没有像名义动物指出的那样报告 GUI 登录(谢谢!)。我使用“pgrep xfce”来检查 XFCE4 是否正在运行。下面打印出当前的 xfce-user:

#!/usr/bin/perl

# Get all processes
my @xfce_processes = `pgrep xfce`;

# If processes exist, get user of first process in list.
if(scalar  @xfce_processes) 
    print `ps -o user h $xfce_processes[0]`;

else

# No xfce processes. 
     ;

【讨论】:

如果有多个 XFCE 会话正在进行怎么办?例如,如果人们使用“切换用户”来允许多个 gui 登录。我将如何获得当前用户?这与我的问题有关:***.com/questions/17996707/…【参考方案3】:

正如您提到的,您的程序作为守护程序运行。因此,它产生的任何进程都将以与启动该守护程序的用户相同的用户身份运行。通过 UI(或任何其他方法)登录的用户永远不会成为您可以通过从您的守护进程调用 whoami 获得的用户。

相反,您应该做的是明确通知您的守护进程登录事件,或者,如果这不是一个选项,请保留当前在盒子上运行的所有登录会话的列表,并查看是否出现新会话 - 这将是新登录用户的会话。

【讨论】:

【参考方案4】:

程序whousers 从文件/var/run/utmp 中获取它们的信息。

文件包含N个“struct utmp”大小的条目,定义在&lt;utmp.h&gt; 您对USER_PROCESS 类型的条目感兴趣。主机字段包含显示。

请注意,如果用户打开某些终端仿真(xterm、konsole...),则同一显示会有多个条目。

您可以监视此文件或 /var/log/wtmp 以获取历史记录

struct utmp ut_entry;
FILE    *fp = fopen(UTMP_FILE, "r");

if( !fp )

  printf("Could not open utmp file!");
  return;


while(fread(&ut_entry, sizeof(struct utmp), 1, fp) == 1)

    if(ut_entry.ut_type != USER_PROCESS)
        continue;

    // string entries are not 0 terminated if too long...
    // copy user name to make sure it is 0 terminated

    char tmpUser[UT_NAMESIZE+1] = 0;
    strncpy(tmpUser, ut_entry.ut_user, UT_NAMESIZE);

    // do more stuff... read the display from ut_entry.host

欲了解更多信息,请参阅utmp manual page

【讨论】:

在某些情况下,登录管理器可能不会使utmp 记录保持最新。例如,我在 Ubuntu 11.04 上的 XFCE4 上看到了这一点。如果这是一个问题,user1439609 可能必须将问题更改为“检测此机器上的所有活动用户”;只需通过扫描/proc/PID/ 目录(使用opendir()readdir()stat())来查看哪些用户帐户正在运行进程,并忽略系统(已知的非人类)用户即可解决。【参考方案5】:

您可能想要调查ConsoleKit 或其更新的化身loginctl。

这些工具专为管理席位和会话而设计,同时保持本地文本控制台、GUI 和远程会话之间的区别。 保证它们会出现在每台 X11 机器上,但如果你的机器是相对较新的,它可能会使用其中一种工具或另一种工具。

【讨论】:

太糟糕了 loginctl 使用 systemd 在发行版中并没有被广泛使用。否则,它看起来非常适合我的问题***.com/questions/17996707/…【参考方案6】:

对于其他来这里使用 xfce4 的人,我要做的是运行 ps -aux | grep xfce4 然后有一行:

root 2497 0.0 0.3 323052 13408 ? Sl 01:24 0:00 xfce4-session

我运行 kill -9 2497 并摆脱了它。对我来说,这是一个我想从 SSH 中杀死的挂起实例。

【讨论】:

以上是关于如何在 Linux 中检测通过 GUI 登录的用户的主要内容,如果未能解决你的问题,请参考以下文章

Kali root用户无法登录GUI界面

如何通过SSH在远程Linux服务器上启动GUI软件?

如何在vue js项目中检测用户的firebase身份验证登录状态?

firebase 如何检测到用户已经在 android 上登录?

Unity - 检测到目标时如何弹出 GUI 按钮

OS X - 如何检测应用程序何时在登录时以隐藏状态启动?