获取 MPlayer 的 PID(不过滤所有进程或失去键盘控制)

获取 MPlayer 的 PID(不过滤所有进程或失去键盘控制)

我经常在工作时播放一些儿童节目。为此,我需要将屏幕扩展到电视、更改音频接收器等。并将 mplayer 窗口从主屏幕移动到所需屏幕 + 使该窗口固定。我知道如何做所有这些,我可以编写该脚本。但要做到这一切,我需要刚刚执行的 MPlayer 的 PID。但是,如果我从 bash 脚本内部运行 MPlayer,mplayer ... &我可以通过获取 PID $!,但脚本结束时我将失去控制 mplayer 的能力。我知道可以通过-slave选项执行 mplayer,但我想以与正常启动 MPlayer 相同的方式控制它。

是否有人知道如何在 bash 脚本中调用 MPlayer,能够获取它的 PID,并且能够在脚本结束时通过正常的 MPlayer 控制台交互来控制 MPlayer?

我也愿意接受其他解决方案,但本质上我需要先以某种方式启动 mplayer,然后获取它的 PID 以便能够运行 pacmd 和 wmctrl 命令,并且所有这些都不会改变执行的 mplayer 的行为。

答案1

下面的脚本执行以下步骤:

  1. 保存原始 stdin 以供日后使用。在您的用例中,它很可能指向终端。
  2. 将 stdin 从 重定向/dev/null,因此默认情况下没有进程(包括未来的子进程)使用原始进程。请注意,/dev/tty直接访问(例如sudo要求输入密码)的进程仍可能会产生干扰。
  3. 在后台运行mplayer,并将 stdin 重定向到原始 stdin。这样它就成为唯一使用它的进程。命令行参数按原样传递。
  4. 等待正确的窗口出现。
  5. 做你想做的事。
  6. 等待mplayer退出。

如果mplayer提前退出,那么脚本将永远不会超越“等待正确的窗口”。因此,最好在后台的子 shell 中执行几个步骤。mplayer退出时,主脚本不应让子 shell 存活。

如果启用了作业控制,该脚本将出现错误,因此不要从具有作业控制的 shell 中获取它。如果获取它,它也可能kill超出您的预期。您应该将脚本作为独立可执行文件运行。

#!/bin/bash

trap 'kill 0' EXIT     # do not let children survive

manage_mp() {
   # wait for window to appear
   until wmctrl -lp | grep -q '\b'"$mppid"'\b.*\bMPlayer\b'; do sleep 1; done

   # do whatever you want to do; the PID is in $mppid in case you lose $!
   # test line below
   wmctrl -r MPlayer -b add,above
}


exec 17<&0             # save stdin
exec 0</dev/null       # redirect stdin, so the original is not used

<&17 mplayer "$@" &    # run mplayer in background
mppid="$!"

manage_mp &

wait "$mppid"          # wait for mplayer

相关内容