【问题标题】:How do you run an application in bash and select which monitor it runs on?如何在 bash 中运行应用程序并选择运行它的监视器?
【发布时间】:2026-01-29 19:50:01
【问题描述】:

我有一个很难找到答案的问题(我总是得到有关显示器操作的答案)。我正在编写一个 bash shell 脚本来帮助我进行代码开发,并且我有两个监视器。

当我运行我编译的可执行文件时,我想告诉它在特定监视器上运行(即与我打开终端的监视器不同,以便我可以在一个屏幕上查看调试并打开应用程序另一个)。

我该怎么做呢?比如:

./myProject > but run on monitor 2

myProject 是我的二进制可执行文件。

谢谢大家。

【问题讨论】:

  • 请说明这是一个图形应用程序,一个简单的控制台应用程序,以及它是否使用任何工具包,如ncurses。
  • 这将取决于您的窗口管理器,以及它如何选择显示新窗口的位置。
  • 当你说在另一台显示器上运行我的可执行文件时。我是否理解正确,您的应用程序是基于 GUI 的应用程序?在这种情况下,bash 与定位无关。您用来创建窗口的库可能有一些锁定窗口位置的方法。
  • 这是一个 GUI (Qt) 应用程序。当我在 bash 中运行应用程序时,它总是在同一监视器上启动应用程序。如果我将终端移动到不同的监视器,则应用程序会在该监视器上启动。

标签: linux qt


【解决方案1】:

如果您在每台显示器上运行单独的显示器(现在不太可能),DISPLAY 环境变量就是您想要的。

但是,如果您使用 Xinerama(将一个逻辑显示分布在多台显示器上),则:

  • 旁白:X11 词汇:“显示器”是一个或多个带有输入设备的“屏幕”;例如键盘和鼠标,又名“座位”。 “屏幕”是部分或全部显示在一个或多个“监视器”上的逻辑画布;当为一个“屏幕”使用多个监视器时,窗口可以部分显示在每个监视器上,但共享相同的 X11 DISPLAY 标识符;这被称为Xinerama。 DISPLAY 格式是 host : display-number . screen-id,例如在我的 Xinerama 设置中,两个显示器都是屏幕0 的一部分,显示编号从0 开始计数,每个登录用户都在同一主机上。 “席位”是使用不同硬件的监视器+输入的逻辑组;使用“虚拟控制台”切换可以发生多个“显示”,这就是 Gnome 和 KDE 允许多个用户在单个“座位”机器上登录的方式。

大多数 GUI 工具包允许您使用 --geometry-geometry 开关指定窗口的几何形状。

  • Qt 使用旧的 MIT 样式 -geometry 形式。 GTK+/Gnome 使用 GNU 风格的--geometry

  • 这假设您允许 Qt 对您的命令行进行后处理,例如将argv 传递给QtApplication 或类似的。

“逻辑显示器”的分辨率是显示器排列的每个方向上的分辨率之和。例如,我现在连接了 2 × 1920×1080 显示器。 xrandr 报道:

Screen 0: minimum 320 x 200, current 3840 x 1080, maximum 8192 x 8192

要在右侧监视器上显示一个窗口,我可以给出一个几何字符串,其 x 坐标在 1920…3839(含)之间。

通常的格式是:widthxheight±x-offset±y-offset — 但如果您喜欢使用默认值,宽度和高度是可选的。 ±+ 相对于顶部/左侧计数,或 - 相对于底部/右侧计数。

所以,例如:

gedit --geometry 800x600+1920+0  # set size at top-left of right screen
gedit --geometry +1920+100       # default size at top-left of right screen
gedit --geometry -0+0            # default size at top-right of entire display

不幸的是,我所知道的从 shell 确定每个监视器上显示区域的唯一编程方法是解析来自 xrandr 的输出;例如

$ xrandr
Screen 0: minimum 320 x 200, current 3840 x 1080, maximum 8192 x 8192
LVDS1 connected (normal left inverted right x axis y axis)
   1366x768       60.0 +
   1024x768       60.0  
   800x600        60.3     56.2  
   640x480        59.9  
VGA1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 510mm x 287mm
   1920x1080      60.0*+
   1680x1050      60.0  
   1280x1024      60.0  
   1440x900       59.9  
   1280x720       60.0  
   1024x768       60.0  
   800x600        60.3  
   640x480        60.0  
   720x400        70.1  
HDMI1 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 510mm x 287mm
   1920x1080      60.0*+
   1680x1050      59.9  
   1280x1024      60.0  
   1440x900       59.9  
   1280x720       60.0  
   1024x768       60.0  
   800x600        60.3  
   640x480        60.0  
   720x400        70.1  
DP1 disconnected (normal left inverted right x axis y axis)

$ xrandr | perl -ne 'if (/(\d+)x(\d+)\+(\d+)\+(\d+)/) '\
> ' { print "$3,$4 - ", $3 + $1 - 1, ",", $4 + $2 - 1, "\n" }'
0,0 - 1919,1079
1920,0 - 3839,1079

(您通常希望避免在 shell 中将 Perl 单行拆分为两行,但 '\...' 的技巧是让它在 SO 上清晰可见。)

【讨论】:

  • 正如我向 John 提到的,我似乎没有 display :0.1 (即使我有两台显示器)。我认为这是因为我的桌面分布在两台显示器上(如果我理解你的解释),这意味着我只有一个显示器。
  • 使用 gedit 我可以使用 --display=DISPLAY,但我不能使用 --geometry 选项......它只是不存在!但我认为你是对的,因为我似乎记得过去使用过一次,我可以看到它的谷歌示例。我有 ubuntu 10.04,所以这已经很老了(工作中的人不太愿意继续前进:(()。但最后我的 Qt 应用程序不支持这种类型的任何选项,所以我想我必须实现它们? - 没有一个 bash 命令告诉启动器(错误...内核?)将窗口放在哪里?
  • 最后...感谢您的详细解释...如果我可以迁移到 Ubuntu 12 甚至 13,我认为这些选项可能会起作用 :)
  • 等等....我弄错了!我认为几何图形不可用,但在某些情况下是可用的。如果我输入(例如)“gedit --help”,我会得到一些帮助,但不是全部。我必须执行 gedit --help-all 然后我会看到完整的选项列表。原来我不能用 gedit 做几何,但我可以做 gnome-terminal 这意味着我可以在与终端相同的窗口中运行我的应用程序(我不能改变它),但我可以打开一个新的 gnome-终端无论我喜欢使用几何,然后使用它来显示我的调试使用 tail -f (或类似)! - 完毕! ......好吧,我必须这样做......但它微不足道。谢谢!
  • 奇怪的是你的 GEdit 缺少那个;它是由 GTK+/GDK(以及 Qt)中的通用代码提供的……请注意,您还可以将 -e 传递给 gnome-terminal 以启动某个程序,或者甚至创建一个配置文件专门用于使用某些设置运行它(例如使用与默认 shell 不同的颜色运行 tail
【解决方案2】:

上面给出并接受的--geometry 答案在许多情况下根本不起作用......

在各种 StackExchange 网站和 AskUbuntu 上都有很多类似的问题,我最终找到的答案(在基于 Ubuntu 14.04 的 Linux Mint 发行版上)是使用 wmctrl。我留下一个答案,因为没有其他人在这个线程上提到它。

(还有一个叫Devil's Pie,另一个叫Compiz,如果你也搜索这些,你会找到我正在谈论的问答)

wmctrl 是您在编写 Bash 脚本时可能正在寻找的一种简单的 unix 工具。我还看到有人建议使用xdotool,这取决于具体目标是什么。

wmctrl 通过窗口标题或pid 提供窗口匹配(不兼容所有类型的 X 管理窗口)

一些有用的资源:

根据我每天工作的位置,我在左侧或右侧连接第二台显示器,我认为我的解决方案将涉及

  • xrandr 中查找尺寸(如BRPocock 的答案所示),
  • 解析以判断哪个是外接显示器(VGA/HDMI 等)而不是内置显示器,
  • 指定尺寸以赋予连接屏幕上的最大化窗口(即左/右/上/下偏移,将根据所使用屏幕的一侧而变化)

留下我的笔记和 [最终] 生成的一些代码 here 以防它对其他人有用。

【讨论】:

  • 对不起 - 这篇文章很晚了,但这篇文章发生了一些活动,所以我现在才注意到你的回答并阅读了它。很酷,刚刚看了一下wmctrl。我仍然使用 --geometry,大多数主要终端都支持它并且它易于使用,但是 +1 是一个漂亮的解决方案,我会试一试:)
【解决方案3】:

使用fifo

在您希望输出出现的监视器上打开一个终端窗口并执行

mkfifo /tmp/myfifo
cat /tmp/myfifo

然后在源终端上做

./myProject >/tmp/myfifo

这假定它是一个控制台应用程序。如果它是图形的,那么您将需要另一种方法,这将取决于您使用的窗口管理器 + 工具包。

【讨论】:

  • hmm... 很酷,但不是我想要的,我的应用程序是一个 GUI... 事实上,让我们说它的 gedit 或 xemacs 或其他东西,我想在另一台显示器上打开它.我正在使用 Ubuntu(如果有帮助?)
  • 暂时没用过ubuntu。您曾经可以通过设置DISPLAY 来控制事物,例如export DISPLAY=:0.1;./myProject(需要处理数字),但现在这可能不适用于多显示器。
【解决方案4】:

您需要做的就是在运行应用程序之前设置DISPLAY 环境变量。

要找出您需要设置的内容,请在您希望它显示的监视器上运行以下命令:

echo $DISPLAY

您应该会看到,例如 :0.1:0.0

然后您可以指定您希望您的应用在该显示器上运行,如下所示:

DISPLAY=:0.1 ./my_app

【讨论】:

  • 感谢那个...我认为它会起作用,但是当我尝试它时,我似乎没有:0.1 显示。我有两个显示器,我的桌面分布在两个显示器上,所以它们不是单独的屏幕。也许如果我使用“双桌面”而不是“传播”那么这会起作用:(
【解决方案5】:

由于您的应用程序使用 QT,您可能正在使用 KDE。在System Settings > Window Behavior > Advanced 中,将Placement 设置为Under Mouse。单击所需的监视器,ALT+Tab 切换到您的终端,然后启动程序。

【讨论】:

  • 我没有 KDE,但我确实在寻找类似的选项...没有成功:( ...我有 Ubuntu 和 gnome