我想知道如何在bash脚本中获取鼠标点击和鼠标移动事件,以实现自己的简单操作系统事件。
请告诉我如何获取这些事件。
xterm终端模拟器定义了一些控制序列来进行鼠标跟踪,您可以在xterm发行版的ctlseqs文档的鼠标跟踪部分中了解更多信息。如果您已经安装了xterm,您可能会在/usr/share/doc/xterm/ctlseqs.txt.gz
或类似路径上找到副本。
大多数在X Window系统上运行的终端模拟器(例如:Konsole、gnome-terminal、eterm等)至少理解其中一些控制序列。如果您想在Linux的虚拟终端之一上直接使用它们,您可能需要运行gpm(8)
。
有几个控制序列可用于启用和禁用鼠标移动报告:
控制序列为CSI ? number h
用于启用,CSI ? number l
用于禁用。CSI可以是ESC [
或字符0x9b
。因此,您可以按以下方式使用它们:
echo -e "\e[?1000h"
然后,按下按钮会得到一堆字符,请参阅ctlseqs或console_codes(4)
了解详情。然后,您可以使用以下命令禁用鼠标跟踪:
echo -e "\e[?1000l"
很遗憾,之前的鼠标报告模式只能处理最多223个坐标(255-32),或在某些情况下为95个坐标(127-32)。因此,有一些新的开关可以改变报告鼠标坐标的格式:
一种好的策略是启用鼠标报告,然后(可选地请求urxvt 1015模式,然后)请求SGR 1006模式。应用程序应该处理新的和旧的鼠标报告响应,以继续在不支持新模式的终端仿真器上工作。
有关新报告模式的更多信息,请参见:
根据这里提供的宝贵信息,再进行一些挖掘后,我们可以捕获鼠标按下和释放、滚轮移动和侧面滚动、中键单击(滚轮单击)以及位置。没有右键。
以下只是一个用于 cli 的 php 示例。它在终端上隐藏了鼠标移动并在退出时正确地设置回来。
它足够冗长,可以适应任何能够阅读 STDIN 并打印到 STDOUT 的编程语言,肯定有很多!
#!/usr/bin/php
<?php
system("stty -icanon"); // Enable shell input
system("stty -echo"); // Disable characters printing
echo "\e[?1003h\e[?1015h\e[?1006h"; // Mouse trap all, urxvt, SGR1006
function shutdown(){ // Cleaning before quiting
echo "\e[?1000l"; // Disable mouse trap
system("stty echo"); // Enable back characters printing
exit; // Cleaned, quit
}
register_shutdown_function("shutdown"); // Handle regular END of script
declare(ticks = 1); // Allow posix signal handling
pcntl_signal(SIGINT,"shutdown"); // Catch SIGINT (CTRL+C)
$KEY = "";
while ($KEY = fread(STDIN,16)) {
$e = explode(";",explode("<",$KEY)[1]);
if ($e[0] === "0" && substr($e[2],-1) === "M"){
echo "BUTTON DOWN, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."\n";
}
if ($e[0] === "0" && substr($e[2],-1) === "m"){
echo "BUTTON UP, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."\n";
}
if ($e[0] === "64"){
echo "WHEEL SCROLL UP, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."\n";
}
if ($e[0] === "65"){
echo "WHEEL SCROLL DOWN, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."\n";
}
if ($e[0] === "1" && substr($e[2],-1) === "M"){
echo "WHEEL BUTTON DOWN, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."\n";
}
if ($e[0] === "1" && substr($e[2],-1) === "m"){
echo "WHEEL BUTTON UP, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."\n";
}
if ($e[0] === "35"){
echo "MOUSE MOVE, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."\n";
}
}
Xterm有一个鼠标跟踪功能
echo -e "\e[?1000;1006;1015h" # Enable tracking
echo -e "\e[?1000;1006;1015l" # Disable tracking
\e[<0;3;21M
,释放则为\e[<0;3;21m
。其中3
是x坐标,21
是y坐标,从左上角计数1开始。(请注意,这是x-y而不是行列)。\e[<64;3;21M
\e[<65;3;21M
Ctrl + v
或输入read
以查看。Readline可以触发bash回调。
bind -x '"\e[<64;": mouse_void_cb' # Cannot be put in .inputrc
bind '"\C-h" : "$(date) \e\C-e\ef\ef\ef\ef\ef"' #Can be put in .inputrc
Readline可以调用多个函数。
# Mouse cursor to begining-of-line before calling click callback
bind '"\C-98" : beginning-of-line'
bind -x '"\C-99" : mouse_0_cb'
bind '"\e[<0;": "\C-98\C-99"'
使用READLINE_POINT
环境变量,Readline回调函数可以更改光标(插入点)位置。
bind -x '"\C-h" : xterm_test'
function xterm_test {
echo "line is $READLINE_LINE and point $READLINE_POINT"
READLINE_POINT=24 # The cursor position (0 for begining of command)
READLINE_LINE='coco' # The command line current content
}
vim /usr/share/doc/xterm/ctlseqs.txt.gz
)\e[<0;3;21m
)存储到变量中以处理事件? - Tcll默认情况下,Bash 不支持鼠标或鼠标点击事件。也没有光标等类似的东西。
您可以安装“通用鼠标服务器”来解决这个问题。例如,可以查看 http://www.linuxfromscratch.org/blfs/view/6.3/general/gpm.html 来在控制台中使用复制和粘贴功能。也许您可以使用这些工具来处理 Bash 脚本。
总之: Bash shell 没有本地的鼠标支持。
我希望你能理解 GoLang :)
基于这条评论。 <3
package main
import (
"fmt"
"strings"
"strconv"
"github.com/pandasoli/goterm"
)
func main() {
termios, _ := goterm.SetRawMode()
defer goterm.RestoreMode(termios)
fmt.Print("\033[?1003h\033[?1015h\033[?1006h") // Mouse trap all, urxvt, SGR1006
fmt.Print("\033[?1002h") // Enable mouse motion reporting
defer fmt.Print("\033[?1002l") // Disable mouse trap
defer fmt.Print("\033[?1003l\033[?1015l\033[?1006l") // Restore mouse mode and SGR1006
for {
key, _ := goterm.Getch()
if key == "q" { break }
if strings.HasPrefix(key, "\033[<") {
list := strings.Split(key[3:], ";")
ev := list[0]
x, _ := strconv.Atoi(list[1])
y, _ := strconv.Atoi(list[2][:len(list[2]) - 1])
kind := list[2][len(list[2]) - 1]
switch ev {
case "0":
if kind == 'M' {
fmt.Printf("(%d, %d) Left mouse down\n", x, y)
} else if kind == 'm' {
fmt.Printf("(%d, %d) Left mouse up\n", x, y)
}
case "1":
if kind == 'M' {
fmt.Printf("(%d, %d) Wheel button down\n", x, y)
} else if kind == 'm' {
fmt.Printf("(%d, %d) Wheel button up\n", x, y)
}
case "2":
if kind == 'M' {
fmt.Printf("(%d, %d) Right mouse down\n", x, y)
} else if kind == 'm' {
fmt.Printf("(%d, %d) Right mouse up\n", x, y)
}
case "32":
if kind == 'M' {
fmt.Printf("(%d, %d) Left mouse pressed move\n", x, y)
}
case "34":
if kind == 'M' {
fmt.Printf("(%d, %d) Right mouse pressed move\n", x, y)
}
case "35":
fmt.Printf("(%d, %d) Mouse move\n", x, y)
case "64":
fmt.Printf("(%d, %d) Wheel scroll up\n", x, y)
case "65":
fmt.Printf("(%d, %d) Wheel scroll down\n", x, y)
default:
code := strings.ReplaceAll(key, "\033", "\\033")
panic(fmt.Errorf("Could not understand mouse input: \"%s\".", code))
}
} else {
result := key
codes := [][]string {
{ "\033", "\\033" },
{ "\b", "\\b" },
{ "\n", "\\n" },
{ "\x7f", "\\x7f" },
}
for _, code := range codes {
result = strings.ReplaceAll(result, code[0], code[1])
}
fmt.Printf("Pressed key \"%s\" %v\n", result, []byte(key))
}
}
}
你可以使用xdotool来模拟鼠标移动和点击事件。 xdotool是一个可以模拟键盘和鼠标的工具。 通过输入以下命令进行安装: sudo apt-get install xdotool。 使用xdotool,你可以自动化几乎所有需要使用键盘和鼠标完成的任务。
apt-get install xautomation
xte 'mousemove 200 300'
因此,鼠标指针移动到屏幕宽度200和高度300。另一个例子是:
xte 'mouseclick 3'
点击鼠标的右键(1:左键,2:中键,3:右键)。此外,您可以通过shell按键盘上的键:
xte 'keydown Control_L' 'key c' 'keyup Control_L'
这个例子向shell发送ctrl+c。
echo -e "\e[?1000l"
: - NVRM