shell脚本:在Linux中模拟击键和鼠标移动, 键盘精灵, xdotool 模拟用户交互

Xdotool的使用

鼠标操作

xdotool支持很多鼠标操作,包括鼠标的移动,左击,右击,滚轮等

  • 鼠标移动到x,y处: xdotool mousemove x y
  • 鼠标点击右键: xdotool click 3
  • 鼠标向上翻滚: xdotool click 4
  • 获取鼠标位置: xdotool getmouselocation

键盘操作

xdotool支持很多键盘操作,常用的使用如下:

  • 按下p键: xdotool key p
  • 按下ctrl+shift+t键: xdotool key ctrl+shift+t
  • 按下p键持续1000ms: xdotool key –delay 1000 p

窗口操作

xdotool支持很多窗口操作,包括窗口的移动,最小化等等

  • 查询主文件夹窗口id: xdotool search –name “主文件夹”
  • 聚焦到id为WID的窗口: xdotool windowfocus WID
  • 移动id为WID的窗口左上角到x,y处: xdotool windowmove WID x y
  • 改变id为WID的窗口大小为w,h: xdotool windowsize WID w h
  • 最小化id为WID的窗口: xdotool windowminimize WID

让Xdotool在Linux定居

对于Ubuntu,Debian或者Linux Mint,你能够只做:

$ sudo apt-get install xdotool

对于Fedora,请使用yum命令:

$ sudo yum install xdotool

对于CentOS用户,可以在EPEL repo中找到该包。在启用EPEL仓库后,只要使用上面的yum命令就可以达成你的愿望。

对于Arch用户,可在Community仓库中找到该包:

$ sudo pacman -S xdotool

如果你还是找不到你的发行版的对应xdotool,你可以从它的官方站点下载。

起步

下面通过一个简单的例子来测试 xdotool 的功能。首先打开图形界面下的终端模拟器,将鼠标移到某个菜单之上,但是不要点击。这时输入焦点应该还在命令行窗口,鼠标位置不动,输入下面的命令:

xdotool click 1

执行这条命灵之后,会发现鼠标悬停处的菜单神奇地打开了,就好像在那里点了左键一样。对 X11 来说,点击鼠标只是一个事件,它并不管这个事件来自鼠标、触摸板、触摸屏还是其他设备,或者是类似 xdotool 这样的软件。

上面的命令中,click 表示动作,1 表示鼠标左键,合法的取值有:

编号 含义
1 鼠标左键
2 鼠标中键
3 鼠标右键
4 滚轮向前
5 滚轮向后

下面考虑复杂一些的情况,如果用 xdotool 来完成自动化,那么需要移动指针到指定的地方。X 桌面坐标系原点位于左上角,x 轴正方向向右,y 轴正方向向下,以像素为单位。例如,本人屏幕分辨率为 1920×1080,那么左上角的坐标为 (0, 0),右上角的坐标为 (1920, 0)。

假设现在需要平铺所有的窗口(我用的是 GNOME 桌面),那么需要将鼠标移到屏幕左上角点击 “Activities” 按钮。使用 xdotool 可以这样实现:

xdotool mousemove 0 0 click 1

xdotool 支持多个命令连在一起,上面的例子中,首先将鼠标移到屏幕左上角,然后点击鼠标左键。

mousemove 指令将鼠标位置移动到指定处,mousemove_relative 以鼠标当前位置为初始,移动相应的距离。这两条指令经常带上 --sync 参数,表示一定要等到 X11 确认鼠标已经移动到了目标位置,才会继续执行。

需要注意的是,如果坐标包含负值,必须在坐标前加上两个减号。例如命令

xdotool mousemove_relative -10 -10

是不能正确执行的,应该使用这种方式:

xdotool mousemove_relative -- -10 -10

 

Xdotool基本功

虽然xdotool是那样的直观,但它仍然是个脚本程序。因此,为了要正确地使用它,你还是得了解它的语法。不过敬请放心,相对于程序的功能而言,语法还是比较简单易学的。

首先,模拟击键是很容易的。你可以从终端敲入下面的命令:

$ xdotool key [name of the key]

如果你想要连接两个键,可以在它们之间使用“+”操作符。它看起来像这样:

$ xdotool key alt+Tab

这两个组合键可以为你切换窗口。

要想让xdotool帮你输入,可以使用以下命令:

$ xdotool type ''

这些对于基本的击键而言已经足够了。但是,xdotool的众多长处之一,就是它可以获取特定窗口的焦点。它可以获取右边的窗口,然后在里面输入,所有你记录下的按键都不会人间蒸发,而是老老实实的如你所愿的出现在那里。要获得该功能,一个简单的命令可以搞定:

$ xdotool search --name [name of the window] key [keys to press]

该命令将在打开的窗口中搜索对应名称的窗口,并聚焦于该窗口,然后模拟击键。

来点更高级的,但很有用哦,xdotool可以模拟鼠标移动和点击,看这命令:

$ xdotool mousemove x y

你可以将光标定位到屏幕坐标(x,y)(像素)。你也可以使用“click”参数来组合:

$ xdotool mousemove x y click 1

这会让鼠标移动到(x,y),然后点击鼠标左键。“1”代表鼠标左键,“2”则是滚轮,“3”则是右键。

最后,一旦你这些命令根植于你脑海,你也许想要实际转储于文件来编辑并试着玩玩。鉴于此,就会有超过一个语句以上的内容了。你需要的就是写一个bash脚本了:

#!/bin/bash
 
xdotool [command 1]
xdotool [command 2]
etc

或者你可以使用:

$ xdotool [filename]

这里你将命令写入到一个独立的文件中,然后通过将文件名作为xdotool命令的参数。

对于文本流的输入,xdotool 提供了一个 type 命令:

xdotool search "gedit" windowactivate --sync type "hello world"

拖拽动作可以分解为“按下鼠标-移动鼠标-释放鼠标”的步骤,下面的代码是一个简单的例子:

xdotool mousedown 1
sleep 0.5
xdotool mousemove_relative --sync 200 200
sleep 0.5
xdotool mouseup 1

意外收获

xdotool 最强大的一个功能,就是能够自动搜索窗口,确定该窗口的位置,并使用窗口的局部坐标。例如,寻找 Chrome 浏览器并激活其窗口,可以通过下面的命令实现:

xdotool search "Chrome" windowactivate

这个功能需要窗口管理器的支持,xdotool 会遍历所有窗口,一旦发现标题栏内容包含指定的关键词,就返回该窗口。如果没有符合规则的窗口,那么什么也不会发生。

这里需要指出的是,窗口的标题栏内容和程序名称没有必然的关系。xdotool 根据标题栏内容查找窗口,而非应用程序的名字。

找到了目标窗口,还不能立刻对窗口中的按钮进行操作,因为窗口可能为于屏幕的任何位置。不过,我们可以将鼠标移动到窗口的左上角:

xdotool search "Chrome" windowactivate --sync mousemove --window %1 0 0

--window X 表示后面的坐标是相对窗口 X 而言的,%1 表示 search 操作返回的第一个窗口。

除了将鼠标移动到窗口的左上角,另一个方案是将窗口移动到指定的位置。例如,将 Chrome 移动到 (50, 50) 处:

xdotool search "Chrome" windowactivate --sync windowmove 50 50

再进一步,还可以指定窗口的大小,例如将 Chrome 缩放到宽 640,高 480 的大小:

xdotool search "Chrome" windowsize 640 480

获取窗口名称

$ xdotool search "Chrome"
Defaulting to search window name, class, and classname
37748741
$ xdotool getwindowname 37748741
JUSTCODE-iKeepStudying - Google Chrome

在打开的窗口中搜索对应名称的窗口,并聚焦于该窗口,然后模拟击键。

#!/bin/bash
export DISPLAY=:1
/opt/google/chrome/chrome --user-data-dir --display=:1 &
#/opt/google/chrome/chrome --user-data-dir --app=http://s.malu.me/ --start-maximized --enable-low-end-device-mode --disable-translate --display=:1 &
WID=`xdotool search --name "Chrome" | head -1`
xdotool windowfocus $WID
xdotool key ctrl+49
sleep 1
xdotool type 'justcode.ikeepstudying'
xdotool key 65

export DISPLAY=:1 用于设置X11默认显示通道,在打开浏览器中会用到

[*注1]: xdotool key ctrl+l 这种别名不再工作。应该使用在xev的输出中找到的值,来替换l。

比如键入l输出:

KeyPress event, serial 40, synthetic NO, window 0x2000001,
    root 0x25, subw 0x0, time 180522539, (110,120), root:(661,427),
    state 0x0, keycode 49 (keysym 0x6c, l), same_screen YES,
    XLookupString gives 1 bytes: (6c) "l"
    XmbLookupString gives 1 bytes: (6c) "l"
    XFilterEvent returns: False

那应该用49替换字母l

chrome常用命令行参数介绍:

1. --incognito,设置浏览器直接从隐身模式启动功能,您在隐身模式中浏览网页不会保留浏览器记录、Cookie存储库或搜索记录,会保留下载的文件和已存的书签。
2. --start-maximized,启动时自动最大化窗口。
3. --lang=en_US,设置语言为英语_美国(这里可以写各种语言代码),快速切换显示语言,而免去在设置中点击数次并重启的麻烦。
4. --user-agent="thatis my user agent"(如果字符串不含空格则无需引号),设置伪造的用户代理字符串,可以验证网站对于不同浏览器采取的不同的行为。
5. --user-data-dir=/userdata,设置自定义用户数据位置,对于系统盘空间较小,希望把用户数据(包含缓存)放在其他位置的用户非常有用。
6. --disable-images,设置为禁止图像,对于流量有限制,或者其他不想看图的人群非常有用。
7. --no-sandbox,不使用沙箱,在和某些杀毒软件有冲突时,可以关闭沙箱。
8. --trusted-plugins,仅使用信任的插件。
9. --restore-last-session,启动时恢复最近的会话。

Chrome命令行参数之基础类:

1. --debug-on-start,如果程序包含基础/调试/debug_on_start_win.h,(仅限于Windows),该过程将​​自启动JIT系统注册的调试器,并会等待60秒钟,让调试器连接到自身并打一个断点。
2. --disable-breakpad,禁用崩溃报告。
3. --wait-for-debugger,在60秒之内,等待一个调试器接入Chrome。
4.--test-child-process,当运行特定的派生子进程的测试,此开关会告诉测试框架,当前进程是一个子进程。
5.--enable-crash-reporter,表示崩溃报告应该启用。由辅助进程不能访问到所需文件的平台作出这个决定,此标志由内部产生。
6.--enable-crash-reporter-for-testing,用于在调试环境中打开Breakpad(一个非常实用的跨平台的崩溃转储和分析模块)崩溃报告,崩溃报告在那里通常会被编译,但被禁用了。
7.--full-memory-crash-report,生成全部内存崩溃报告。
8.--enable-low-end-device-mode,改写低端设备检测,启用低端设备的优化。
9.--disable-low-end-device-mode,改写低端设备检测,禁止低端设备的优化。

Chrome其它收集命命令行参数:

disable-accelerated-compositing    禁用加速
disable-winsta    禁用渲染备用窗口
disable-application-cache    禁用应用程序缓存
disable-apps  禁用应用程序
disable-audio    禁用音频
disable-auth-negotiate-cname-lookup
disable-background-networking  禁用后台联网
disable-backing-store-limit    禁用存储数量限制,可以防止在打开大量的标签窗口时,页面出现闪烁的现象。
disable-byte-range-support    禁用缓存的支持字节范围
disable-click-to-play    禁用点击播放
disable-connect-backup-jobs    如果超过指定的时间,则禁用建立备份的TCP连接
disable-content-prefetch    禁用内容预取
disable-custom-jumplist    禁用Windows 7的JumpList自定义功能
disable-databases    禁用HTML5的数据库支持
disable-desktop-notifications    禁用桌面通知(默认窗口启用)
disable-dev-tools    禁用所有页面的渲染检测
disable-device-orientation    禁用设备向导
disable-webgl    禁用WebGL实验功能
disable-extensions    禁用扩展
disable-extensions-file-access-check    禁用扩展文件访问检查
disable-geolocation    禁用地理位置的JavaScript API
disable-glsl-translator    禁用GLSL翻译
disable-hang-monitor    禁止任务管理器监视功能
disable-internal-flash    禁用内部的Flash Player
disable-ipv6    禁用IPv6
disable-preconnect    禁用TCP/IP协议
disable-javascript    禁用JS
disable-java    禁用Java
disable-local-storage     禁用本地存储
disable-logging    禁用调试记录
disable-new-tab-first-run  禁用新标签显示的通知
disable-outdated-plugins    禁用过时的插件
disable-plugins    禁止插件
disable-popup-blocking    禁用阻止弹出窗口
disable-prompt-on-repost
disable-remote-fonts    禁用远程字体
disable-renderer-accessibility    禁用渲染辅助功能
disable-restore-background-contents    当浏览器重新启动后之前的网址被记录
disable-session-storage    禁用会话存储
disable-shared-workers    禁用共享,功能尚未完成
disable-site-specific-quirks    禁用指定站点设置的WebKit兼容性问题。
disable-speech-input    禁用语音输入
disable-ssl-false-start    禁用SSL的虚假启动
disable-sync    禁用同步
disable-sync-apps    禁用同步应用程序
disable-sync-autofill    禁用同步自动填表
disable-sync-bookmarks    禁用同步书签
disable-sync-extensions    禁用同步扩展
disable-sync-passwords    禁用同步密码
disable-sync-preferences    禁用同步偏好设置
disable-sync-sessions    禁用同步会话
disable-sync-themes    禁用同步主题(皮肤)
disable-sync-typed-urls    禁用同步输入网址
disable-tab-closeable-state-watcher    
disable-translate    禁用翻译
disable-web-resources    禁用网络资源后台加载服务
disable-web-security    禁用网络安全提示?
disable-web-sockets    禁用网络接口
safebrowsing-disable-auto-update  禁用自动升级(安全浏览)
disable-tls    禁用设置XMPP协议的客户端同步控制
disable-flash-core-animation    禁用Flash核心动画
disable-hole-punching    禁用Punching
disable-seccomp-sandbox    禁用沙盒
no-sandbox      启动无沙盒模式运行

作为本文的一个意外收获,这里是xdotool的一个具体实例。你可能听说过,也可能没听说过Bing —— 微软的搜索引擎。在后面的实例中,你会看到你可能从没听过Bing奖励:一个程序,可以让你用Bing积分兑取亚马逊的礼物卡和其它的一些礼物卡(LCTT 译注:我是从来没听说过~)。要赚取这些积分,你可以每天在Bing上搜索累计达30次,每次搜索你都会获得0.5个积分。换句话说,你必须把Bing设为默认搜索引擎,并每天使用它。

或者,你可以使用xdotool脚本,在这个脚本中,会自动聚焦到Firefox(你可以用你喜欢的浏览器来取代它),并使用fortune命令生成一些随机单词来实施搜索。大约30秒之内,你的日常搜索任务就完成了。

#!/bin/bash
 
for i in {1..30}
do
  WID=`xdotool search --title "Mozilla Firefox" | head -1`
  xdotool windowfocus $WID
  xdotool key ctrl+l
  xdotool key Tab
  SENTENCE="$(fortune | cut -d' ' -f1-3 | head -1)"
  xdotool type $SENTENCE
  xdotool key "Return"
  sleep 4
done

下面来个小结吧:我真的很喜欢xdotool,即便它的完整功能超越了本文涵盖的范围。这对于脚本和任务自动化而言,确实是种平易的方式。负面的问题是,它可能不是最有效率的一个。但我要再说一遍,它忠于职守了,而且学习起来也不是那么麻烦。

简单示例

#!/bin/bash

function open(){
    for((i=0;i<5;i++));
    do
        nautilus "/home/"
        kill -2 `ps -A | grep nautilus | cut -f-1 -d' '`
    done
}

#测试不断的打开和关闭文件浏览器
open  
nautilus "/home/"
sleep 5
WID=`xdotool search --name "文件浏览器" | tail -1`
echo $WID
xdotool windowfocus $WID

#gen the random num in [0, max)
function random(){
    if [[ $# -eq "0" ]]; then
        max=1000
    else
        max=$1
    fi
    rand_value=$[$RANDOM % $max]
    echo $rand_value
}

function drag(){
    x0=0
    y0=0
    xdotool windowmove $WID $x0 $y0
    for((i=0;i<500;i++));
    do
        #xdotool key ctrl+t
        x=$[$x0+$i]
        y=$[$y0+$i]
        xdotool windowmove $WID $x $y
        #xdotool windowminimize $WID 
        #sleep 4
    done
}

function move(){
    x1=`random`
    y1=`random`
    xdotool windowmove $WID $x1 $y1
}

function contineMove(){
    for((i=0;i<10000;i++));
    do
        move
        #sleep 1
    done
}

function resize(){
    x1=`random`
    y1=`random`
    xdotool windowsize $WID $x1 $y1
}

function contineResize(){
    for((i=0;i<$1;i++));
    do
        resize
    done
}


#拖拽窗口
#drag   

#移动窗口
#contineMove

#改变窗口大小
#contineResize 10000

官方参考手册

在有些平台,编译安装xdotool之后,只能使用xdotool –help简单的查看命令,不能使用man xdotool查看手册,这里把上面的内容和官方参考手册一起作成pdf,以供下载使用.

下载:xdotool.pdf

 

shell脚本:在Linux中模拟击键和鼠标移动, 键盘精灵, xdotool 模拟用户交互
shell脚本:在Linux中模拟击键和鼠标移动, 键盘精灵, xdotool 模拟用户交互

 

本文:shell脚本:在Linux中模拟击键和鼠标移动, 键盘精灵, xdotool 模拟用户交互