` 你是否曾经拥有一个梦 ——你的计算机 可以自动为你干活? 或许,并非因为 你刚看了终结者。 然而,除此之外 脚本和任务自动化 是每个高级用户追寻的梦…
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 模拟用户交互