当我从本地用户 crontab 运行下面的脚本时,在sudo
before /usr/bin/FreeFileSync
(脚本的最后一行)中,我的 GUI 上会打开一个小的进度窗口,一切顺利。唯一的问题是我必须输入我的 sudo 密码,这使得它具有交互性并且有点笨拙。
运行 FFS 需要 root 权限,否则它会抱怨没有权限访问正在备份的某些目录和文件。
#!/bin/bash
# define default display and pass it on to any child process
# from within the running shell
DISPLAY=:0.0
export DISPLAY
/usr/bin/FreeFileSync /home/user/bu-1.ffs_batch 2> \
/home/user/bu-1.ffs_log
当我使用从我的根 crontab 调用相同的脚本时sudo crontab -e
,FreeFileSync
由于以下错误而无法运行:
$ cat /home/user/bu-1.ffs_log
16:35:01: Error: Unable to initialize GTK+, is DISPLAY set properly?
正如您所看到的,我export DISPLAY=:0.0
在脚本和我的根 crontab 文件中配备了:
$ sudo crontab -e | head -4
[sudo] password for user:
1 SHELL=/bin/bash
2 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
3 HOME=/
4 MAILTO=root
有人能帮忙解决这个错误吗?
编辑:是否可能是因为用户root
没有打开会话,因此没有可显示的标准输出,导致从 root 的 crontab 运行该程序失败?
我可以通过要求 root 显示当前用户会话的标准输出来解决这个困难吗?如果可行的话似乎值得一试;如果可以我该怎么做?
答案1
你可以配置sudo
为不需要特定命令的密码然后返回使用非 root cron。为此,假设用户 ID 为“user”的用户想要以 root 身份运行命令,请使用以下FreeFileSync
命令创建一个文件/etc/sudoers.d/user
user ALL = NOPASSWD: /usr/bin/FreeFileSync
命令必须带有完整路径名。如果您没有明确列出命令的参数,则 sudo 将允许任何参数。将其替换ALL
为您的主机名(而不是 localhost)会更加安全。
假设文件/etc/sudoers
有以下行:(注意#是不是一条评论)
#includedir /etc/sudoers.d
如果没有,则只需将用户条目添加到 /etc/sudoers。编辑此文件时请小心:使用 visudo,或确保您已以 root 身份登录或拥有运行 root 的 shell,以便能够进行任何修复。
您的用户 crontab 条目可以只包含以下命令:
DISPLAY=:0.0 sudo /usr/bin/FreeFileSync /home/user/bu-1.ffs_batch 2>/home/user/bu-1.ffs_log
ubuntu sudo 将为命令保留一些环境变量,包括 DISPLAY 和 HOME(参见的输出sudo sudo -V
),以便程序能够读取 ~/.Xauthority 文件(继续阅读以了解详细信息)。
或者,继续使用 root crontab:
如果你ps alxww|grep X
发现你的 X11 服务器正在运行一个-auth
选项,如下所示:
/usr/bin/X :0 ... -auth /var/run/lightdm/root/:0 ...
这意味着客户端必须使用文件中的机密进行连接/var/run/lightdm/root/:0
。此文件在用户的文件中保存机密的副本~/.Xauthority
。这个“机密”只是一个任意的随机数。如果您是 root,则可以读取这两个文件,因此您的客户端只需在环境中提供:
XAUTHORITY=/var/run/lightdm/root/:0
或者,您可以将 HOME 设置为显示用户的 HOME,
HOME=/home/user
以便.Xauthority
在那里找到正确的文件。
或者,您可以将秘密从此处导出到 root 的主目录:
xauth -f /home/user/.Xauthority nextract - localhost/unix:0 | sudo xauth -f /root/.Xauthority nmerge -
然后是 XAUTHORITY=/root/.Xauthority 或者只是 HOME=/root。