我介于 Linux 新用户和中级用户之间。
我正在为一个小组设置本地网络,并且需要配置在互联网连接丢失时自动登录门户网站。
当我在树莓派(RASPBIAN OS)本身上使用监视器运行 bash 脚本时,我可以正常工作,顺序是:
使用 fping 检查互联网是否已关闭 --> 打开 xterm --> 让 xdotool 打开 w3m 并自动单击并输入密码。
这是我的压缩形式的代码:
DNSPing=$(fping 9.9.9.9)
EtecsaPing=$(fping 10.180.0.30)
...
if [[ ( $EtecsaPing == "10.180.0.30 is alive" ) && ( $DNSPing == "9.9.9.9 is unreachable" ) ]]
then
echo "ETECSA UP - Internet all down - Run login script now"
xterm &
sleep 2
xdotool type "w3m -m https://10.180.0.30:8443/"
xdotool key Return
...
xdotool type <USER>
xdotool key Return
xdotool sleep 1
...
xdotool key Return
xdotool type <PASSWORD>
xdotool sleep 1
...
xdotool key Return
sleep 5
killall xterm
fi
因此,当我连接显示器和鼠标并运行它时,它工作得很好。
我想让这个无头运行并在 crontab 中使用脚本,经过 2 天的尝试,我觉得我只是在兜圈子。
问题是新的 xterm 会话和 xdotool 都需要定义 DISPLAY 才能运行。
为此,我安装了 xvfb,它创建了一个模拟显示。
sudo Xvfb :10 -ac -screen 0 1024x768x24
DISPLAY=:10 xterm & (the script from above)
运行没有任何错误,但它也不起作用。
如果我运行:
sudo Xvfb :10 -ac -screen 0 1024x768x24
DISPLAY=:10 xterm -e "echo 'deb blah ... blah' | sudo tee -a /CronJobs/yap.txt > /dev/null"
它将回显添加到文件中,因此我知道我的显示器正在运行 xterm 会话,并且我得出结论,模拟显示器和 xterm 会话都正常工作。
如果我做:
sudo Xvfb :10 -ac -screen 0 1024x768x24
DISPLAY=:10 xterm &
DISPLAY=:10 xdotool type "sudo echo 'deb blah ... blah' | sudo tee -a /CronJobs/yap.txt > /dev/null"
DISPLAY=:10 xdotool key Return
这是行不通的。
总之,xdotool 正在工作(没有错误),但没有做任何事情!
所以我认为 xdotool 没有输入 xterm 终端,因为未选择该窗口,我尝试选择 xterm 窗口,然后得到:
DISPLAY=:10 xdotool getactivewindow
Your windowmanager claims not to support _NET_ACTIVE_WINDOW, so the attempt to query the active window aborted.
xdo_get_active_window reported an error
在这一点上,我的项目是如此独特,以至于我找不到任何好的建议来做什么。一些人尝试将 windowmanager 替换为 Xvfd,但数量很少且复杂。
用简单的话来说:
如何让 Xvfd 表现得更好,像真正的显示器一样?
我可以让linux忘记所有DISPLAY变量和windowmanager,而只是无条件地以普通用户身份运行脚本吗?如何?
我能否以更智能的方式自动化登录序列,从而避免使用 xdotool?
我的网络是私有的,我对可能损害树莓派安全性的解决方案没有任何问题,因此禁用任何 xhost 等都可以,我只是不知道如何/什么。
提前致谢。
答案1
我正在回答我自己的问题,因为 Fosforo 激励我尝试一些解决问题的方法。
使用当前的活动程序套件,您无法xvfb
使用来操作窗口xdotool
。
xdotool
仍然允许获取信息,例如,您可以运行以下命令找到 xterm 窗口的 PID:
DISPLAY=:10 xdotool search --name "xterm"
在您的例子中,您获得的活动 xterm 会话的 PID 为 2097165。
现在,您通常可以使用以下命令激活窗口:
DISPLAY=:10 xdotool windowactivate 2097165
但是当你运行xvfb
这个时会返回以下错误:
Your windowmanager claims not to support _NET_ACTIVE_WINDOW, so the attempt to activate the window was aborted.
xdo_activate_window on window:2097165 reported an error
因此您无法主动操纵焦点 - 您可以DISPLAY
通过运行以下命令找到默认焦点:
DISPLAY=:10 xdpyinfo | grep focus
这将通知您:
focus: PointerRoot
焦点为PointerRoot
意味着您键入的任何内容都会输入到光标所在的窗口中。
使用之前的 PID,您可以通过运行以下命令快速找到 xterm 窗口的位置和大小:
DISPLAY=:10 xwininfo -id 2097165
这告诉你:
Absolute upper-left X: 0
Absolute upper-left Y: 0
Relative upper-left X: 0
Relative upper-left Y: 0
Width: 484
Height: 316
...
使用xdotool
您可以类似地获取鼠标位置:
DISPLAY=:10 xdotool getmouselocation
这告诉您您的鼠标位置是:
x:512 y:384 screen:0 window:904
换句话说;您的鼠标不在 xterm 窗口的顶部,因此您使用 xdotool 类型键入的任何内容都不会放入 xterm 窗口中。
存在两种非常简单的解决方案;
- 移动鼠标
- 使 xterm 窗口变大。
由于您在启动时知道并控制屏幕分辨率xvfb
,因此第二个选项是最简单的。
您只需添加-geometry
到 xterm 的启动参数中,就变成:
sudo Xvfb :10 -ac -screen 0 1024x768x24
DISPLAY=:10 xterm -geometry 1024x768+0+0 &
这将使 xterm 窗口达到全尺寸,从而确保鼠标位于窗口上方,之后xdotool
诸如 key 和 type 之类的命令将起作用。
-geometry
换句话说,将参数添加到 xterm 是为了回答您的问题。
答案2
尝试使用getwindowname
它来调试它。
xdotool search --onlyvisible --name 'TITLE_YOUR_WINDOW' getwindowname
并将其输出到文件中。
一些基本的窗口管理器接受getwindowname
但不接受getactivewindow
。
第二个选项是使用 vncserver。它非常适合执行自动化操作的无头桌面。多年来一直在做。