将特定信号发送到外部 USB 键盘?或者,我如何修复 fdopen()?

Und*_*ndo 6 osx usb

一些背景:当我从命令行运行命令时,我试图让外部键盘上的大写锁定灯按命令点亮。理想情况下,它可以编写脚本,以便我可以将它用于警报和其他事情(我拆卸了键盘)。

我得到了这个看起来应该可以工作的命令:

fd=fdopen("/dev/console"); ioctl(fd, 0x4B32, 0x04);
Run Code Online (Sandbox Code Playgroud)

当我尝试在 OS X 或我放置的 Ubuntu 服务器上运行此命令时,会发生这种情况:

me@server1:~$ fd=fdopen("/dev/console"); ioctl(fd, 0x4B32, 0x04);
-bash: syntax error near unexpected token `('
me@server1:~$ fd=fdopen(/dev/console);
-bash: syntax error near unexpected token `('
Run Code Online (Sandbox Code Playgroud)

所以看起来问题出在第一部分。我需要安装一套软件/实用程序吗?如何手动控制外接键盘上的大写锁定指示灯?

And*_*ese 6

您的问题是您尝试在 shell 提示符中输入 C 代码,这显然不起作用。您可以将其放入正确的 C 文件中,编译它并获得可以执行的有效二进制文件:

#include <linux/kd.h>

#include <sys/ioctl.h>

#include <fcntl.h>
#include <unistd.h>

#include <err.h>
#include <stdio.h>
#include <stdlib.h>

static void
usage(char *argv0)
{
    fprintf(stderr, "Usage: %s <on|off>\n", argv0);
    exit(EXIT_FAILURE);
}

int
main(int argc, char *argv[])
{
    int fd;
    int on;
    unsigned char state;

    if (argc != 2)
        usage(argv[0]);

    if (strcmp(argv[1], "on") == 0)
        on = 1;
    else if(strcmp(argv[1], "off") == 0)
        on = 0;
    else
        usage(argv[0]);


    fd = open("/dev/console", O_RDWR);
    if (fd == -1)
        err(EXIT_FAILURE, "open /dev/console");

    if (ioctl(fd, KDGETLED, &state) == -1)
        err(EXIT_FAILURE, "KDGETLED");

    if (on)
        state |= LED_CAP;
    else
        state &= ~LED_CAP;

    if (ioctl(fd, KDSETLED, state) == -1)
        err(EXIT_FAILURE, "KDSETLED");

    close(fd);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

把它放在一个名为 eg 的文件中caps.c并编译它:

$ gcc -o caps caps.c
Run Code Online (Sandbox Code Playgroud)

然后你可以运行它

$ ./caps on
Run Code Online (Sandbox Code Playgroud)

打开 LED 或

$ ./caps off
Run Code Online (Sandbox Code Playgroud)

将其关闭(切换留给读者作为练习)。

注意:要打开/dev/console您需要超级用户权限。

另一个注意事项:这也不会阻止您的终端或 X 服务器偶尔更改 CapsLock LED(例如Caps按下时)。这也不适用于 OS X,但仅适用于 Linux,因为没有标准化的方法来执行此操作。最后,您不能单独更改多个键盘上的 LED。