简体   繁体   English

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

[英]How to unlock Gnome Keyring from Python running on a Cron Job?

I'm hooking a Python script up to run with cron (on Ubuntu 12.04), but authentication is not working.我正在连接一个 Python 脚本以与 cron 一起运行(在 Ubuntu 12.04 上),但身份验证不起作用。

The cron script accesses a couple services, and has to provide credentials. cron 脚本访问几个服务,并且必须提供凭据。 Storing those credentials with keyring is easy as can be, except that when the cron job actually runs, the credentials can't be retrieved.使用keyring环存储这些凭据非常简单,只是当 cron 作业实际运行时,无法检索凭据。 The script fails out every time.脚本每次都失败。

As nearly as I can tell, this has something to do with the environment cron runs in. I tracked down a set of posts which suggest that the key is having the script export DBUS_SESSION_BUS_ADDRESS .据我所知,这与 cron 运行的环境有关。我追踪了一组帖子,这些帖子表明关键是让脚本导出DBUS_SESSION_BUS_ADDRESS All well and good, I can get that address and, export it, and source it from Python fairly easily.一切都很好,我可以很容易地获得该地址并导出它,然后从 Python 获取它。 But it simply generates a new error: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 .但它只会生成一个新错误: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 Setting DISPLAY=:0 has no effect.设置DISPLAY=:0无效。

So, has anybody figured out how to unlock gnome-keyring from Python running on a Cron job on Ubuntu 12.04?那么,有没有人想出如何从在 Ubuntu 12.04 上运行的 Cron 作业上运行的 Python 解锁gnome-keyring环?

I'm sorry to say I don't have the answer, but I think I know a bit of what's going on based on an issue I'm dealing with.很抱歉,我没有答案,但我想根据我正在处理的问题,我知道一些正在发生的事情。 I'm trying to get a web application and cron script to use some code that stashes an oauth token for Google's API into a keyring using python-keyring.我正在尝试获取一个 Web 应用程序和 cron 脚本,以使用一些代码将 Google API 的 oauth 令牌存储到使用 python-keyring 的密钥环中。

No matter what I do, something about the environment the web app and cron job runs in requires manual intervention to unlock the keyring.无论我做什么,关于 Web 应用程序和 cron 作业运行的环境都需要人工干预才能解锁密钥环。 That's quite impossible when your code is running in a non-interactive session.当您的代码在非交互式会话中运行时,这是完全不可能的。 The problem persists when trying some tricks suggested in my research, like giving the process owner a login password that matches the keyring password and setting the keyring password to an empty string.在尝试我的研究中建议的一些技巧时问题仍然存在,例如为进程所有者提供与密钥环密码匹配的登录密码并将密钥环密码设置为空字符串。

I will almost guarantee that your error stems from Gnome-Keyring trying to fire up an interactive (graphical) prompt and bombing because you can't do that from cron.我几乎可以保证您的错误源于 Gnome-Keyring 试图启动交互式(图形)提示和轰炸,因为您无法从 cron 执行此操作。

Install keychain:安装钥匙串:

sudo apt-get install keychain

Put it in your $HOME/.bash_profile :把它放在你的 $HOME/.bash_profile 中:

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

It will ask your password at the first login, and will store your credentials until next reboot.它会在第一次登录时询问您的密码,并将存储您的凭据直到下次重新启动。

Insert it at the beginning of your cron script:将其插入 cron 脚本的开头:

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

If you use other language such as python, call it from a wrapper script.如果您使用其他语言(例如 python),请从包装脚本中调用它。

It works for me, I hope it helps you too.它对我有用,我希望它对你也有帮助。

Adding:添加:

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

at the beginning of the script listed in the crontab worked for me.在 crontab 中列出的脚本的开头为我工作。 I still needed to unlock the keyring interactively once after a boot, but reboots are not frequent so it works ok.我仍然需要在启动后以交互方式解锁密钥环一次,但是重新启动并不频繁,所以它工作正常。

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

so the full script run by cron would be:所以 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

using an environment from conda.使用来自 conda 的环境。 Or change the python invocation to however you set up python to be run.或者将 python 调用更改为您设置要运行的 python。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM