通过systemd运行Python脚本无法加载模块

时间:2016-07-22 13:06:05

标签: python linux service systemd

我有一个使用lazy var signedURL: String = { let epochTime = NSDate().dateByAddingTimeInterval(60*5).timeIntervalSince1970 let resourceURL = "resource url" let keyPairId = "your pair id" let keyPairPrivateKeyName = "name of pem file" let myurl = String(format: "%@?Expires=%.0f&Signature=%@&Key-Pair-Id=%@", resourceURL, epochTime,self.getSignature(resourceURL, expiresOn: epochTime, privateKey: keyPairPrivateKeyName), keyPairId) return myurl }() func encodeStringForCloudFront(signature aSignature: String) -> String { var signature = aSignature signature = signature.stringByReplacingOccurrencesOfString("+", withString: "-") signature = signature.stringByReplacingOccurrencesOfString("=", withString: "_") signature = signature.stringByReplacingOccurrencesOfString("/", withString: "~") return signature; } func getSignature(resourceURL: String, expiresOn: NSTimeInterval, privateKey keyPairPrivateKeyName: String) -> String { let signString = String(format: "{\"Statement\":[{\"Resource\":\"%@\",\"Condition\":{\"DateLessThan\":{\"AWS:EpochTime\":%.0f}}}]}", resourceURL, expiresOn) guard let filePath = NSBundle.mainBundle().pathForResource(keyPairPrivateKeyName, ofType: "pem"), let privateKeyData = NSData(contentsOfURL: NSURL(fileURLWithPath: filePath)) else { return "Error loading pem file." } guard let str = String(data: privateKeyData, encoding: NSUTF8StringEncoding) else { return "Private Key Data is not valid" } do { let signatureString = try SwiftyRSA.signString(signString, privateKeyPEM: str) return self.encodeStringForCloudFront(signature: signatureString) } catch { return "Something goes wrong URL NotValid" } } 的Python脚本,我通过zmq安装了这个库,如果通过命令行手动调用,我可以正常运行程序。但是,只要我尝试使用pip install zmq单位调用该脚本,运行systemd就会显示systemctl status myservice.service

我的服务文件如下所示:

ImportError: No module named zmq

其中[Unit] Description=Does Something [Service] Type=simple ExecStart=/bin/sh /var/lib/project/runpythonscript.sh Restart=always [Install] Alias=myservice.service 是一个非常简单的shell脚本,以root身份运行我的python脚本。从命令行手动运行这个shell脚本可以完全正常地运行我的python程序,但是进行服务调用会导致它找不到runpythonscript.sh模块。

感谢任何帮助。

5 个答案:

答案 0 :(得分:8)

systemd以root身份运行。通过pip安装的模块是为用户而不是系统安装的,因此安装没有root权限的模块会使模块无法访问root。

为了解决这个问题,我运行了sudo -H pip install zmqsudo -H pip3 install zmq来为root用户安装Python 2.7和Python 3+的软件包。这允许systemd在尝试执行Python脚本时访问模块。

答案 1 :(得分:2)

最可能的解释是你有一些环境变量设置(例如你的PYTHONPATH的扩展名?),当systemd运行脚本时没有设置。

您可以尝试使用Environment参数(请参阅[0]),因此请将PYTHONPATH(以及其他可能影响此问题的内容)设置为控制台会话中的任何内容。

[0] http://0pointer.de/public/systemd-man/systemd.exec.html#Environment=

答案 2 :(得分:2)

将此属性添加到[Service]部分,以确保systemd以指定用户身份运行。

User=pi

请参阅AndyD的解决方案。

答案 3 :(得分:0)

在我的情况下,我将“EnvironmentFile =”设置为用户.bash_profile。问题是.bash_profile我有类似的东西:

export PYTHONPATH=....
export PATH=....

这对systemd无效,我不得不将其更改为:

PYTHONPATH=....
PATH=....
export PYTHONPATH PATH

答案 4 :(得分:0)

我有一个类似行为的问题,但原因并非完全相同。无论如何,我是在这里答复,以防其他人碰到它。

我的问题是我试图直接启动脚本(BAD)

ExecStart=/var/lib/project/runpythonscript.sh

代替通过/ bin / sh(GOOD)

ExecStart=/bin/sh /var/lib/project/runpythonscript.sh

我的原始方式实际上适用于许多其他脚本,它们执行了各种操作。但是,当Shell脚本文件运行Python时,它失败了。