2013年3月14日星期四

如何延时GNOME的自动启动程序

环境是Ubuntu 12.04 GNOME 3.2。GNOME可以通过Startup Applications这个应用来设置自动启动的程序。Dropbox就是通过这里自动启动的。我发现每次刚刚进入桌面系统负载都很高,用top查看与Dropbox有关系。
从右上角的菜单打开
我想让Dropbox延迟两分钟再启动,这样可以让GNOME启动的速度加快,体验会好一点。我试图在Dropbox的启动命令前面加上sleep 120来延时,但这样后Dropbox根本就不自动启动了。
更改自动启动程序的对话框
我打算探个究竟,搞定我的问题。先通过ps找到启动这个程序的命令是gnome-session-properties,通过dpkg -S /usr/bin/gnome-session-properties找到对应的包名,然后下载源代码包gnome-session,在Eclipse里面创建项目。

不知道相关的文件是哪个?竟然是从翻译文件po/zh_CN.po里面看出来的,在capplet目录下。在gsm-app-dialog.c里面有这样的代码:
if (gsm_util_text_is_blank (exec)) {
        error_msg = _("The startup command cannot be empty");
} else {
        if (!g_shell_parse_argv (exec, &argc, &argv, &error)) {
                if (error != NULL) {
                        error_msg = error->message;
                } else {
                        error_msg = _("The startup command is not valid");
                }
        }
}
看起来这是判断启动命令的代码。安装好相关的开发包之后,在Eclipse里面可以看到g_shell_parse_argvglib.h里面声明的。文档里面说了,这个函数不支持Shell的很多特性。看来我的命令行'sleep 120; dropbox start -i'被解析成了不能执行的命令。写了如下一个测试程序test_gshell.c
#include <glib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
    const char *exec = argv[1];
    GError     *error;
    const char *error_msg;
    char      **myargv;
    int         myargc;
    if (!g_shell_parse_argv (exec, &myargc, &myargv, &error)) {
        if (error != NULL) {
            error_msg = error->message;
        } else {
            error_msg = "The startup command is not valid";
        }
    }
    printf("%d\n", myargc);
    for(int i = 0; i < myargc; i++) {
        printf("%s\n", myargv[i]);
    }
}
用如下的命令编译出执行文件:
gcc -o test_gshell test_gshell.c \
    -I/usr/include/glib-2.0/ \
    -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ \
    -L/lib/x86_64-linux-gnu/ \
    -L/usr/lib/x86_64-linux-gnu/ \
    -L/lib64/ -lglib-2.0 -std=c99
然后测试我的命令:
$ ./test_gshell "sleep 120; dropbox start -i"
5
sleep
120;
dropbox
start
-i
看到GLib把我本来期望的两条命令的List解析成了sleep命令后面跟4个参数,相当于执行了如下Shell命令:
sleep "120;" "dropbox" "start" "-"
这个命令显然不能达到我的目的。

我翻墙的脚本也是通过GNOME来自启动的,有时候网络还没好,就希望能够延时执行,那个脚本可以带命令行的延时参数。现在要让Dropbox延时启动,我也只能用一个脚本把延时和Dropbox的命令封装起来,然后再让GNOME自动运行这个脚本。主要要在Dropbox的设置里把自动启动去掉。

没有评论:

发表评论