我的问题涉及两个程序(kodi 和 xscreensaver)。由于我在其他应用程序中也遇到过这种情况,所以让我更笼统地说,我有两个应用程序,即 App1 和 App2。我希望 App2 从启动到关闭持续运行,但我经常在计算机旁使用 App1。有时我什至在离开时忘记关闭 App1。如果 App1 未运行,我希望 App2 以默认设置运行。如果 App1 正在运行,那么我希望 App2 改变它的行为,但是如果 App1 已经运行了很长时间(比如一个半小时),那么 App2 应该恢复正常设置。
我认为我可以使用 bash 脚本和其他东西(例如 cron 或 start-stop-daemon)来完成此任务。以下是我迄今为止在 bash 中所做的操作,位于名为 Action_Needed.sh 的文件中:
#!/bin/bash
# Determine if App1 and App2 are running at the same time
# Exit with 0 if yes, Exit with 1 if not
ps -e | grep -q "App1"
if [ $? -eq 0 ]
then
# App2 should always be running, but check
# anyway. This could potentially be used
# to restart App2 automatically, if for some
# reason it was closed or crashed.
ps -e | grep -q "App2"
if [ $? -eq 0 ]
then
return 0
else
return 1
fi
else
return 1
fi
很简单,可以将此脚本与 Cron 一起使用,每分钟左右执行一次,并在上述脚本以状态 0 退出时更改 App2 的行为。
如果App1正在运行,并且已经运行了很长时间(比如一个半小时),而我希望App2继续正常运行,我该怎么办?我应该使用 Cron 以外的其他东西吗?
答案1
因此,我认为您想要检查具有给定名称的进程,并根据它是否正在运行以及它已经运行了多长时间来进行一些选择?
要查找进程的进程 ID,您可以 grep 的输出ps
,或使用pidof
注释中链接的示例,或者类似地使用pgrep
。无论您的系统有哪个。 (例如pgrep
在procps
Debian 上的软件包中。)
您想要的另一件事是目标程序的运行时间。在较新的 Linux 系统上,您可以使用它ps --no-headers -oetimes $PID
来获取自进程启动以来的时间(以秒为单位)。
所以,像这样:
#/bin/sh
target="App1"
# target=$1 # uncoment to take the target from the command line
pid=$(pgrep --oldest "$target")
if [ -n "$pid" ] ; then
time=$(ps --no-headers -oetimes "$pid")
echo "Oldest $target has been running for $time seconds"
if [ "$time" -gt 5400 ] ; then
echo "That's more than 1.5 hours"
fi
fi
但请注意,如果搜索匹配多个进程pgrep
,( 和pidof
) 将很乐意返回多个 PID。您必须以某种方式处理这个问题,要么使匹配范围足够窄(pgrep -f
在这里可能很有用),选择--newest
or --oldest
,pgrep
或者修改脚本以仅采用程序的 PID 输出之一。
答案2
不要使用 *sh 进行高级过程控制。从本质上讲,这也取消了 SysVinit 的资格。您始终可以通过每一次痛苦的边缘情况故障来修补和附加初始化脚本,直到它看起来总是正确地工作,然后继续对其负责,直到下一个任务出现。
systemd 支持带有依赖项的作业,upstart 也是如此。两者还具有用于运行用户 GUI 的“用户会话”模式,如下所示。