如何从在 Cron 作业上运行的 Python 解锁 Gnome 密钥环?

问题描述 投票:0回答:4

我正在连接一个 Python 脚本以与 cron 一起运行(在 Ubuntu 12.04 上),但身份验证不起作用。

cron 脚本访问几个服务,并且必须提供凭据。使用

keyring
存储这些凭据非常简单,只不过当 cron 作业实际运行时,无法检索凭据。脚本每次都会失败。

据我所知,这与 cron 运行的环境有关。我找到了一组帖子,这些帖子表明关键是脚本导出

DBUS_SESSION_BUS_ADDRESS
。一切顺利,我可以相当轻松地获取该地址并将其导出并从 Python 获取它。但它只是生成一个新错误:
Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
。设置
DISPLAY=:0
没有效果。

那么,有人知道如何从在 Ubuntu 12.04 上的 Cron 作业上运行的 Python 解锁

gnome-keyring
吗?

python ubuntu cron python-keyring gnome-keyring-daemon
4个回答
3
投票

很抱歉我没有答案,但我想我根据我正在处理的问题知道了一些正在发生的事情。我正在尝试获取一个 Web 应用程序和 cron 脚本来使用一些代码,这些代码使用 python-keyring 将 Google API 的 oauth 令牌存储到密钥环中。

无论我做什么,Web 应用程序和 cron 作业运行的环境都需要手动干预来解锁密钥环。当您的代码在非交互式会话中运行时,这是完全不可能的。当尝试我的研究中建议的一些技巧时,问题仍然存在,例如为进程所有者提供与密钥环密码匹配的登录密码并将密钥环密码设置为空字符串。

我几乎可以保证你的错误源于 Gnome-Keyring 试图启动交互式(图形)提示和轰炸,因为你不能从 cron 做到这一点。


0
投票

安装钥匙扣:

sudo apt-get install keychain

将其放入您的 $HOME/.bash_profile 中:

if [ -z "$SSH_AUTH_SOCK" ] ; then
  eval `ssh-agent -s`
fi
eval `keychain --eval id_rsa`

它会在第一次登录时询问您的密码,并会存储您的凭据直到下次重新启动。

将其插入 cron 脚本的开头:

source $HOME/.keychain/${HOSTNAME}-sh

如果您使用其他语言(例如 python),请从包装器脚本中调用它。

它对我有用,希望对你也有帮助。


0
投票

添加:

PID=$(pgrep -u <replace with target userid> bash | head -n 1)
DBUS="$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/"$PID"/environ | sed 's/DBUS_SESSION_BUS_ADDRESS=//' )"
export DBUS_SESSION_BUS_ADDRESS=$DBUS

在 crontab 中列出的脚本开头对我有用。启动后我仍然需要以交互方式解锁密钥环一次,但重新启动并不频繁,所以它可以正常工作。

(来自 https://forum.duplicacy.com/t/cron-job-failed-to-get-value-from-keyring/1238/3

因此 cron 运行的完整脚本将是:

#! /usr/bin/bash

PID=$(pgrep -u <replace with target userid> bash | head -n 1)
DBUS="$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/"$PID"/environ | sed 's/DBUS_SESSION_BUS_ADDRESS=//' )"
export DBUS_SESSION_BUS_ADDRESS=$DBUS

/home/user/miniconda/conda run -n myenv python myscript.py

使用 conda 的环境。或者将 python 调用更改为您设置要运行的 python 的方式。


0
投票

这里晚了几年。但对于那些遇到同样问题的人,我刚刚在Come and Tech it中找到了解决方案。基本上需要在python脚本的开头添加以下代码

import os
os.environ['DBUS_SESSION_BUS_ADDRESS'] = 'unix:path=/run/user/USERID/bus'
os.environ['DISPLAY'] = ':0'

然后就可以正确访问密钥环了。 'USERID'的值可以通过shell中的'id'命令获取。

© www.soinside.com 2019 - 2024. All rights reserved.