我尝试过使用管道和重定向来让(C 程序或脚本)输出最终出现在输入缓冲区上,printf "\033[6n"
但没有得到积极的结果。
有谁知道这是怎么可能的:
- 命令行
- 在 shell 脚本中
- C代码
管道输出_cmd_ > /dev/stdin
和 C 代码fprintf(stdin, "blah\n");
没有可测量的影响。
笔记:我不想将输入“通过管道”输出到另一个命令,我想将字符“注入”到“键盘缓冲区”(事实上)。
编辑:最初的用例是一个沙盒 cli 应用程序,允许shell
或system
外部命令与操作系统(例如Bas)交互,但是不是处理文件描述符。
答案1
编辑:简短的回答曾是 /dev/uinput
,现在是TIOCSTI
(见帖子末尾)
这是迄今为止的答案,并针对评论:
ioctl_tty(2)
TIOCSTI
我没有,但是在内核源代码上查找(通过自由电子)将显示tiocsti
“假输入字符”,它使用上下文tty_struct
。
相关应用程序始终以交互方式运行,因此无法使用管道和重定向。它可以shell
用于编写脚本,但是,与许多其他类似的应用程序不同,它不会也不允许捕获结果,只允许stdin
&stdout
按照正常方式执行操作。
在可预见的未来,没有机会改变这一点,这不是我的申请。但是,我能够剪切 的结果"\033[6n"
,这些结果已由内核通过tty_insert_flip_char
& tty_schedule_flip
in注入到键盘缓冲区中src/drivers/tty/tty_buffer.c
,它使用tty_port
上下文。
如果没记错的话,在 FD 文件结构改变之前,当有仅有的4个文件描述符,也许可以实现这一点。如今,虽然您可以写入/dev/stdin
或/proc/self/fd/0
,但它们已连接到/dev/tty#
TTY 设备,写入到 TTY 设备的任何内容最终都会显示在屏幕上 ( /dev/stdout
)。使用 TTY 时,内核似乎绕过了文件描述符路由,请注意这些flip
函数将其称为港口。
任何用户态应用程序都无法访问这些内核函数中的任何一个。在 X-Windows 下,可以使用xvkbd
和xdotool
或xte
,但此应用程序正在 linux (VT) 控制台上使用。
(几乎)真实的答案:
尽管/dev/uinput
没有用户权限(在大多数系统上),但所有参数都将起作用sudo
的脚本printf
。
或者,键盘事件也将起作用,因为所有用户都可以访问它,但它每次启动和每个系统都会发生变化(我的通常是/dev/input/event0
,但并非总是如此)。
经过进一步研究,这些方法都不实用,尤其是对于脚本编写。我们需要了解需要做什么,我们只是想呈现文本在输入缓冲区上,而不是“模拟按键”(这是上述设备的工作方式)。
(最实用的)真实答案:
一个场外问题引用了 stackexchange 上的答案,从 2011 年开始(这里)。它用TIOCSTI
。再次查看 Perl 示例后,它对于不提供应用程序的脚本编写也可能很实用。
perl -le 'require "sys/ioctl.ph";
ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV
' `_cmds_`
然而,它也将其回显到屏幕上。经过几个小时的进一步研究和实验,以下内容在脚本或命令行中是实用的:
stty -echo; perl -le 'require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV ' `_cmds_` ;stty echo
笔记:虽然TIOCSTI
被撤销于OpenBSD 6.2(2017 年 10 月),显然 Linux 内核开发人员属于对面的请记住,断然拒绝撤销它(您可以在OpenBSD 期刊)。
答案2
从 Debian Bullseye 开始,console-tools
被吸收到kbd
其中的writevt
是不是包括。如果您需要,可以在本文末尾的更新中链接来源。
writevt /dev/tty# text
,至少在 Linux 上,也许是 BSD 和 Unix,它目前是软件包的一部分console-tools
。用户必须拥有写VT 的权限。具体来说,(编辑:如果它在您的操作系统上可用)OP的完整且正确的答案是:
writevt `tty` "`_cmds_`"
这个问题表明 StackExchange 社区作为一个整体缺乏对基础操作系统的深入了解。writevt
非常古老,它是 99%(编辑:Debian Linux)系统上安装的基本命令。直到 2002 年 6 月,Debian 中还没有它的手册页或维护者,这也许可以解释为什么很多人不知道它,尽管那是 15 年前的事了。然而,即使在 Kali Linux(它有一切)它通常不会列在下面可用的 命令,尽管它从一开始就存在。
从 Debian Buster 开始,writevt
默认情况下不再安装,并且根据某些人的说法,甚至可能不再存在于任何软件包中(由于缺少维护者?或软件包发生变化console-tools
?)
更新:如果事实上我无法再console-tools
在 debian 软件包搜索中找到(我最初验证了内容),甚至无法向后移植。
原始包项目在这里:
不需要补丁。 Raspbian/RPiOS 具有 debian 版本(Wheezy 到 Buster):
http://raspbian.raspberrypi.org/raspbian/pool/main/c/console-tools/
引用 Yan Dirson 的话:
当前(公共)软件项目 我参与 Debian GNU/Linux 项目,自 1997 年以来我一直是该项目的成员。
http://ydirson.free.fr/en/software/
console-tools
“Linux Console Tools”项目中的软件包在 RPiOS 中仍然可用。它与linuxconsoletools
“Linux Console Project”项目中的包不同,该项目也在 SourceForge 上。