在 Bash 中发送模拟击键

Ish*_*han 24 linux bash automation

我最近一直在尝试编写一个脚本,该脚本可用于在 bash 中自动化我的 c++ 程序。如果您了解 AutoIt,我可以简单地向您展示我正在尝试做的事情的示例:

send("1{enter}")
Run Code Online (Sandbox Code Playgroud)

或者

send("!a")
Run Code Online (Sandbox Code Playgroud)

OK 对于那些不会说 AutoIt 的人:

第一个示例发送模拟的“1”击键,然后是 enter(CR)

第二个例子发送alt-a

我特别想在bash 中做到这一点。其他脚本语言都做不到

另外,我喜欢用勺子喂食。请具体说明如何写。不允许为我编写脚本。

Den*_*nis 22

您正在寻找xdotool

xdotool 相当于您的示例命令是:

xdotool key 1 Return
xdotool keydown Alt key a keyup Alt
Run Code Online (Sandbox Code Playgroud)

  • @Ishan:**几乎不可能用纯 bash 代码做这样的事情**。Bash 不能直接使用 X11,也不能使用任何现有的 X11 库。您必须直接连接到 X11 套接字(bash 只支持 TCP,而不是 Unix 套接字),手动解析 X11 协议(在 bash 中解析二进制数据注定会失败)并制作适当的响应。bash 是一个 shell,它**设计**通过链接外部工具来工作。 (12认同)

use*_*686 19

要将文本输入程序的标准输入,请使用管道和/或重定向

echo 1 | myprogram

(echo "First line"
 echo "Second line") | myprogram

myprogram <<EOF
First line
Second line
EOF
Run Code Online (Sandbox Code Playgroud)

对于交互式 CLI 程序(不是全终端程序),可以使用命名管道或协进程作为一种穷人expect(由于是 Tcl,您排除了这种情况):

mkfifo in out
myprogram <in >out &
echo "First line" >in
read -r reply <out

mkfifo in out
myprogram <in >out &
exec {infd}>in {outfd}<out
echo "First line" >&$infd
read -r reply <&$outfd

coproc foo { myprogram; }
echo "First line" >&${foo[1]}
read -r reply <&${foo[0]}
Run Code Online (Sandbox Code Playgroud)

(从输出管道读取时要小心;例如,head -1 <out不会只读取一行——它会缓冲一个完整的 4k 块,打印一行,丢弃其余的。)


小智 6

我最喜欢的是“tmux”。

警告-这里有一定程度的填鸭式的内容,尽管这个问题已经足够老了,原作者无疑已经完成了他们最初的意图。

您可以轻松地在后台启动 tmux,启动应用程序。Tmux 提供了一个 API,用于将击键发送到应用程序,以及将应用程序连接到终端(如果您想与其交互)。

例子:

$ tmux new-session -d -s Super
$ tmux send-keys -t Super: "uuid" "Enter"
$ tmux capture-pane -t Super: -S - -E - -p | cat -n
Run Code Online (Sandbox Code Playgroud)

$ uuid

fe253d00-3432-11eb-9984-cb225a8f7d48

$ tmux kill-session -t Super:
Run Code Online (Sandbox Code Playgroud)

new-session -d -s Super创建一个Super在后台调用的新会话 (-d)。注意-snew-session 命名为session。我还没有命名要运行的应用程序,因此启动了一个 shell。

send-keys -t Super: "command" "Enter"发送击键。Tmux 理解许多关键字,如 Enter、PgUp、Escape 等,否则通过send-keys -t Super: $'command\n'也可以发送 UTF 和原始代码。请注意-t指的是包含 的目标[session]:[window id]:[pane #]。由于我只有默认窗口和窗格,因此我将它们留空并仅引用会话。如果我知道没有其他会话正在运行,我就可以-t完全省略。

capture-pane -t Super: -S [start] -E [end] -p复制窗口的内容。默认情况下,窗格会捕获到内部缓冲区,您可以保存或粘贴到其他窗口。这-p会导致内容通过管道传送到屏幕。请注意,捕获的数据可能比全屏长得多。

最好的部分是,如果您让应用程序或会话保持运行,tmux attach -t Super:则会将您带入正在运行的会话,以便您可以与应用程序交互。

许多人使用 tmux 来启动长时间运行的交互式程序,作为他们可以稍后附加的后台服务,或者作为自动化测试解决方案的一部分。