如何在Bash中获取当前鼠标坐标?

44

我需要在Bash中获取当前鼠标坐标,但是xdotool似乎对我不起作用。我该怎么做?


从哪里开始?一个X服务器?Curses?... - Anders Lindahl
2
“xdotool getmouselocation” 报告了什么错误?调试可能比想出替代方案更容易。 - ghoti
5个回答

72
为避免使用所有的sed/awk/cut等命令,你可以使用:
xdotool getmouselocation --shell

特别是,

eval $(xdotool getmouselocation --shell)

该命令将把位置分别存入shell变量XYSCREEN中。之后,

echo $X $Y

这将提供一个片段,可随后用于xdotool mousemove或其他任何用途。


我的额外操作是对几个位置进行顺序点击的文件positions.txt(通过几次eval/echo运行给出):

123 13
423 243
232 989

使用这个代码的示例:

while read line; do
     X=`echo $line| cut -c1-3`; 
     Y=`echo $line| cut -c4-7`;
     xdotool mousemove --sync $((  0.5 + $X )) $(( 0.5 + $Y ));
     xdotool click 1
done < positions.txt

如果不需要缩放像素(与我的情况不同),那么可以简单地执行

while read line; do
     xdotool mousemove --sync $line;
     xdotool click 1
done < positions.txt

现在该命令还输出WINDOW=...,这似乎解决了https://dev59.com/kpHea4cB1Zd3GeqPvu3Q的问题。 - Nemo

33

试一下这个:

# Real time mouse position.
watch -t -n 0.0001 xdotool getmouselocation 

当你移动鼠标时,这将实时显示你的鼠标位置在"x"和"y"上。您可以将坐标保存到文件中以供以后参考或在脚本中使用以自动化这些鼠标移动方式:

# Save real time mouse coordinates to file.
while true; do xdotool getmouselocation | sed -e 's/ screen:0 window:[^ ]*//g' >> coordinates.txt; done

这将仅记录鼠标坐标到coordinates.txt文件中。如果您想重复记录时采取的操作,可以在脚本中使用每行内容。按下ctrl+c即可结束录制会话。

这只是展示了xdotool在AFK自动化和其他方面的强大实用性的一个小样例。甚至可以制作自定义机器人 :D

(编辑)

如果您需要从sed命令中去除x:y:,则可以添加逻辑OR|,同时使用-E选项进行扩展正则表达式,如下所示:

xdotool getmouselocation | sed -E "s/ screen:0 window:[^ ]*|x:|y://g"

如果您想使用重定向和命令替换来缩短命令,则可以使用以下命令而不是管道:

sed -E 's/ screen:0 window:[^ ]*|x:|y://g' <<< $(xdotool getmouselocation)

免责声明:sed正则表达式是为GNU sed编写的,可能在不同平台或sed版本上无法正常工作。


谢谢。你能进一步从coordinates.txt中去掉“x:”和“y:”吗?你如何读取它们并重新播放? - Tim
好的,我已经编辑了答案以反映您的要求。 - Yokai

4
你指的“xdotool不工作”是什么意思?
下面是输出结果:
xdotool getmouselocation

无论如何,如果您能编译 C 程序,请参考以下链接: http://dzen.geekmode.org/dwiki/doku.php?id=misc:xget-mouse-position 关于您在下面的评论中提到的问题:
Warning: XTEST extension unavailable on '(null)'. Some functionality may be disabled; See 'man xdotool' for more info. x:654 y:453 screen:0 window:1665

我猜你在Windows XP上看到的是两行:

Warning: XTEST extension unavailable on '(null)'. Some functionality may be disabled; See 'man xdotool' for more info. 
x:654 y:453 screen:0 window:1665

如果是这种情况,您应该像这样重定向 STDERR

xdotool getmouselocation 2>/dev/null

这样就可以跳过警告。

如果您的唯一输入是光标位置行,则将其导入 sed 可以得到坐标,如下所示:

xdotool getmouselocation 2>/dev/null | \
sed 's/x:\([0-9]\+\)[ \t]y:\([0-9]\+\)[ \t].*/\1;\2/'
# OUTPUT should by something like:  "654;453"

如果您想使用坐标(使用bash):
export COORDINS=`xdotool getmouselocation 2>/dev/null | sed 's/x:\([0-9]\+\)[ \t]y:\([0-9]\+\)[ \t].*/\1;\2/'`
export XPOS=${COORDINS/;*/}
export YPOS=${COORDINS/*;/}

HTH


我收到一个警告:在“(null)”上不可用XTEST扩展。某些功能可能被禁用;有关更多信息,请参阅“man xdotool”。 x:654 y:453 screen:0 window:1665 - t3hcakeman
我该如何使用awk/grep/sed来处理这个问题? - t3hcakeman
谢谢!我可以将每个X和Y设置为单独的变量吗?再次问一下,我该如何设置? - t3hcakeman
不,我指的是在终端中实际输入命令。它不会改变。 - t3hcakeman
所以你已经输入了所有三个 export ... 命令,然后做了这样的事情:echo $XPOS $YPOS,然后将光标移动到另一个位置,然后重新发出那些 export ... 命令和 echo ...,但是它没有改变?在我看来,这是不可能的。你能否将终端行粘贴到像 https://gist.github.com/ 这样的 pastebin 服务中,并提供链接以查看它? - Zsolt Botykai
显示剩余9条评论

2
如果您正在使用xterm终端,您可以发出转义序列ESC [ ? 9 h,这将使xterm在鼠标单击时向控制程序(即bash)发送一个转义序列。我不知道其他终端仿真器是否具有类似的功能。
有关xterm中鼠标跟踪的信息,请参阅http://www.xfree86.org/current/ctlseqs.html#Mouse

2
提一下 ESC [ ? 9 l 可以让 xterm 退出此模式,这样你的鼠标就可以正常工作了。 :) - ghoti

1

我收到警告:'(null)'上不可用XTEST扩展。某些功能可能已被禁用;有关更多信息,请参见'man xdotool'。x:654 y:453 screen:0 window:1665

所以它对你来说是有效的。您只需要解析命令的输出。您可以使用zsolt上面发布的sed脚本或其他各种选项:

  xdotool getmouselocation 2>/dev/null | cut -d\  -f1,2 -
  // returns something like "x:2931 y:489"

或者

  xdotool getmouselocation 2>/dev/null \
   | awk 'BEGIN{RS=" ";ORS=RS} {split($0,a,":");} a[1]~/^[xy]$/{print a[2];}'
  // returns something like "2931 489 "

或者

  xdotool getmouselocation 2>/dev/null | sed 's/ sc.*//; s/.://g; s/ /x/'
  // returns something like "2931x489"

有很多种方法可以解决这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接