Cron 作业可以使用 Gnome-Open 吗?

Posted

技术标签:

【中文标题】Cron 作业可以使用 Gnome-Open 吗?【英文标题】:Can Cron Jobs Use Gnome-Open? 【发布时间】:2012-01-03 09:22:22 【问题描述】:

我正在运行 Ubuntu 11.10(Unity 界面)并创建了一个 Bash 脚本,该脚本使用“gnome-open”打开我每天早上使用的一系列网页。当我在终端中手动执行脚本时,bash 脚本工作得很好。这是脚本的一个示例(都是一样的,所以我把它缩短了):

#!/bin/bash

gnome-open 'https://docs.google.com';
gnome-open 'https://mail.google.com'; 

由于它似乎运行良好,我在我的 crontab(我的,而不是 root 的)中添加了一个作业,以便在每个工作日的特定时间执行。

这是 crontab 条目:

30 10 * * 1,2,3,4,5 ~/bin/webcheck.sh

问题是 bash 脚本中的每个“gnome-open”命令都会返回此错误:

GConf-WARNING **:客户端无法连接到 D-BUS 守护进程: 无法在没有 $DISPLAY for X11 的情况下自动启动 dbus-daemon GConf 错误:没有运行 D-BUS 守护程序 错误:未指定显示

我进行了一些搜索以试图解决这个问题。我尝试的第一件事是使用 SIGHUP 重新启动守护进程:

killall -s SIGHUP gconfd-2

这不起作用,所以我尝试使用 dbus-launch 手册页中的以下代码启动 dbus-daemon:

## test for an existing bus daemon, just to be safe
         if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then
## if not found, launch a new one
         eval `dbus-launch --sh-syntax --exit-with-session`
         echo "D-Bus per-session daemon address is: $DBUS_SESSION_BUS_ADDRESS"
         fi

但这并没有做任何事情。

我尝试在我的 bash 脚本顶部简单地添加“dbus-launch”,但这也不起作用。

我还尝试编辑 crontab 以包含 Bash 的路径,因为我在另一个线程上看到了该建议,但没有奏效。

关于如何启动和运行它的任何想法?

【问题讨论】:

记录一下:使用保存会话的浏览器(Chrome、Opera、Firefox 都支持它!),最好使用pinned 标签到(Chrome 和 Firefox;Opera 有堆叠标签 i> 也是。赢了!)。这样,您就不必玩这些技巧来打开浏览器选项卡:) 就个人而言,我讨厌固定标签。但是感谢您在下面的回答,我会玩一下,看看是否可以将其合并到我的脚本中。 【参考方案1】:

这是解决问题的方法。事实证明,这个问题主要是由于 Bash 无法访问 X 窗口会话(或者至少我是这么理解的)引起的。所以我的问题通过像这样编辑我的 crontab 解决了:

30 10 * * 1,2,3,4,5 export DISPLAY=:0 && ~/bin/webcheck.sh

“export DISPLAY=:0”语句告诉 cron 使用哪个显示器。在搜索“未指定显示”或类似内容后,我在这个存档的 Ubuntu 论坛上找到了答案:

http://ubuntuforums.org/archive/index.php/t-105250.html

所以现在,每当我登录时,恰好在 10:30,我的系统将自动启动一系列我每天都需要查看的网页。省去了我每次都输入我的三个字母别名的繁琐过程:)

【讨论】:

【参考方案2】:

很高兴你问到!

这取决于它何时运行。

如果 Gnome GDM Greeter 处于活动状态,您可以在登录对话框中使用 DBUS 会话,如果您愿意的话。例如,如果没有人登录,您可以使用它向登录屏幕发送通知:

function do_notification

    for pid in $(pgrep gnome-session); do
        unset COOKIE
        COOKIE="$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$pid/environ|cut -d= -f2-)"
        GNUSER="$(ps --no-heading -o uname $pid)"

        echo "Notifying user $GNUSER (gnome-session $pid) with '$@'"
        sudo -u "$GNUSER" DBUS_SESSION_BUS_ADDRESS="$COOKIE" /usr/bin/notify-send -c "From CRON:" "$@"
    done

    unset COOKIE

如您所见,上面的代码只是在所有可用的 gnome-session 上运行相同的命令 (notify-send),调用时如下:

do_notification "I wanted to let you guys know"

您可能可以将其拆开并用于您自己的目的。

【讨论】:

第一次会话通常可以依靠DBUS_SESSION_BUS_ADDRESS=$HOME/.dbus/session-bus/$(dbus-uuidgen --get)-0 @ehemient:很好。但是如果没有 vty 登录,你会使用 哪个 home? 再次感谢您的帮助。所以我做了一些研究来逐行了解你的脚本在做什么。我想我明白了。因此,为了实现我的目的,我基本上需要使用“pgrep”方法来确定 gnome-session PID,然后从 gnome-session 中获取 DBUS_SESSION_BUS_ADDRESS 并将其设置在 gnome-open 中。我假设我还必须使用 COOKIE 变量来取消设置 gnome-open 中的 DBUS_SESSION_BUS_ADDRESS 以整齐地清理东西? @metaflops 好吧,DBUS_* 变量仅在写入时存在于超级用户 shell 中。 COOKIE、GNUSER 循环变量只是让事情变得……不那么难以辨认的本地人。我可以(应该)在我的函数中将 COOKIE/GNUSER 作为本地声明。我想我在写这篇文章时并不知道这一点,我想通过取消设置 COOKIE 来防止“泄漏”最后使用的 DBUS* 信息(这实际上不如 local 安全因为它可能会覆盖同名的全局 shell 变量)。 好的,所以你会在变量声明前面写“local”,而忘记“未设置”业务,因为变量包含在函数中?

以上是关于Cron 作业可以使用 Gnome-Open 吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 php 脚本创建 cron 作业?

cron 作业会杀死最后一个 cron 执行吗?

使用 cron 作业运行 wp cli 命令

Laravel 中的 Cron 作业 [重复]

使用 R 和 SQL Server 的 Cron 作业

给定时间内的 Cron 作业和随机时间