我在 bash 中编写了一个小脚本,可以打开一个文件,然后五分钟后关闭它。它会不断重复这个过程。
问题是,无论鼠标指向哪里,程序都会打开,我希望它在我的第二台显示器上打开,该显示器的尺寸非常适合查看文件。
我尝试以以下方式(在命令行)使用显示变量:export DISPLAY=:0.1。但此后我从 CLI 调用的任何程序都会返回错误。(错误:无法打开显示:0.1)
有人有建议吗?
编辑:
这是每五分钟打开一个名为 thesis.pdf 的文件的脚本
#! /bin/bash
while true; do
evince /home/adam/Desktop/Thesis.pdf &
sleep 5m
ps -ef | grep "Thesis.pdf" | awk '{print $2}' | xargs kill
done
exit 0
答案1
要定位窗口,您可以使用操纵 X 事件的工具,例如xdotool
或wmctrl
。例如,对于wmctrl
,您可以使用-e
:
-e <MVARG>
Resize and move a window that has been specified with a -r
action according to the <MVARG> argument.
<MVARG>
A move and resize argument has the format 'g,x,y,w,h'. All five
components are integers. The first value, g, is the gravity of
the window, with 0 being the most common value (the default
value for the window). Please see the EWMH specification for
other values.
The four remaining values are a standard geometry specification:
x,y is the position of the top left corner of the window, and
w,h is the width and height of the window, with the exception
that the value of -1 in any position is interpreted to mean that
the current geometry value should not be modified.
您通常可以忽略重力,因此要将窗口放置在屏幕左上角并使其尺寸为 1200 x 700 像素,您可以运行:
wmctrl -r :ACTIVE: -e 1,1,1,1200,700
让-r
您选择一个窗口,:ACTIVE:
意味着当前聚焦的窗口。
您还可以简化脚本。没有必要解析ps
,特殊变量$!
保存最近放置在后台的作业的 PID。无论如何,解析ps
通常会失败,因为可能有多个进程与 匹配Thesis.pdf
。总会有两个:evince
和grep Thesis.pdf
您刚刚运行的 。
因此,考虑到所有这些,您可以这样做:
#! /bin/bash
while true; do
## Open the pdf
evince ~/doc/a.pdf &
## Save the PID of evince
pid="$!"
## Wait for a 1.5 seconds. This is to give the window time to
## appear. Change it to a higher value if your system is slower.
sleep 1.5
## Get the X name of the evince window
name=$(wmctrl -lp | awk -vpid="$pid" '$3==pid{print $1}')
## Position the window
wmctrl -ir "$name" -e 1,1,1,1200,700
## Wait
sleep 5m
## Close it
kill "$pid"
done
请注意,我删除了exit 0
,因为由于您的while true
,它永远不会到达,并且没有意义。您可以使用位置参数来确定要将窗口放置在何处。
最后,关于 的注释DISPLAY
。此变量指向 X 显示器。这不是屏幕,而是活动的 X 服务器。许多用户可能在一台机器上运行并行 X 服务器,这允许您选择窗口应显示在哪个服务器上。它与连接的物理屏幕数量完全无关,除非每个屏幕都在运行单独的 X 会话。
答案2
这个答案假设你正在使用 Unity:
编写脚本在特定屏幕或位置打开应用程序时会遇到什么问题
如果你想调用一个应用程序,随后将其窗口放置在特定的位置和大小,则呼叫应用程序和窗口实际出现,是必不可少的,但不可预测;如果您的系统被占用,则该时间可能比空闲时长得多。
您需要一种(最好是“智能”)方法来确保定位/调整大小在窗口出现后(立即)完成。
下面的脚本(编辑版这个) 会在桌面的任意位置(第二个显示器上)打开一个应用程序,可能以文件作为参数。它会等待窗口出现,然后再将窗口移动到其位置和大小,因此无论您的系统是否缓慢(或占用),它都会正确运行。
剧本
#!/usr/bin/env python3
import subprocess
import time
import sys
app = (" ").join(sys.argv[5:])
get = lambda x: subprocess.check_output(["/bin/bash", "-c", x]).decode("utf-8")
ws1 = get("wmctrl -lp"); t = 0
subprocess.Popen(["/bin/bash", "-c", app])
while t < 30:
ws2 = [w.split()[0:3] for w in get("wmctrl -lp").splitlines() if not w in ws1]
procs = [[(p, w[0]) for p in get("ps -e ww").splitlines() \
if app in p and w[2] in p] for w in ws2]
if len(procs) > 0:
w_id = procs[0][0][1]
cmd1 = "wmctrl -ir "+w_id+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w_id+" -b remove,maximized_vert"
cmd3 = "xdotool windowsize --sync "+procs[0][0][1]+" "+sys.argv[3]+"% "+sys.argv[4]+"%"
cmd4 = "xdotool windowmove "+procs[0][0][1]+" "+sys.argv[1]+" "+sys.argv[2]
for cmd in [cmd1, cmd2, cmd3, cmd4]:
subprocess.call(["/bin/bash", "-c", cmd])
break
time.sleep(0.5)
t = t+1
如何使用它
安装
xdotool
和wmctrl
。我使用了两个都因为调整大小wmctrl
可能会导致(具体来说)出现一些特殊情况Unity
。sudo apt-get install wmctrl sudo apt-get install xdotool
将下面的脚本复制到一个空文件中,将其保存为
setwindow
(无扩展名)~/bin
;如有必要,创建目录。- 使脚本可执行(!)
- 如果您刚刚创建
~bin
,请运行:source ~/.profile
使用以下命令测试运行脚本(例如)
setwindow 0 0 50 100 gedit /path/to/file.txt
换句话说:
setwindow <horizontal-position> <vertical-position> <horizontal-size (%)> <vertical-size (%)> <application> <file_to_open>
如果一切正常,请在需要的地方使用该命令。
在右侧显示器上打开应用程序
如果您连接了第二台显示器,您应该将组合屏幕视为一个大的虚拟桌面,如下例所示。
在这个例子中,为了将窗口放在右侧屏幕上,您只需使其 x 位置大于左侧屏幕的 x 分辨率。(在这种情况下 > 1680)。
要以最大化方式使用应用程序打开文件,请将和都<horizontal-size (%)>
设置<vertical-size (%)>
为100
。
小问题
wmctrl
在 Unity 中,当您使用或(重新)定位和(重新)调整窗口大小时xdotool
,窗口将始终与屏幕边框保持较小的间距,除非您将其设置为 100%。您可以在上图 (3) 中看到;当窗口inkscape
放置在x
位置 0 时,您仍然可以看到 Unity Launcher 和窗口之间的微小间距inkscape
。
答案3
我在这里进行绝对的盲目尝试,但现在的解决方法可能是使用这个脚本:
#!/bin/bash
# Author: Andrew Martin
# Credit: http://ubuntuforums.org/showthread.php?t=1309247
echo "Enter the primary display from the following:" # prompt for the display
xrandr --prop | grep "[^dis]connected" | cut --delimiter=" " -f1 # query connected monitors
read choice # read the users's choice of monitor
xrandr --output $choice --primary # set the primary monitor
我相信这对我来说是有效的,将我的中间显示器而不是我的笔记本电脑显示器设置为“主显示器”。理论上,这会在主显示器中打开你的程序?--我知道你说它会在鼠标所在的位置打开,但这有点困难...
希望您能解决它:)