python 脚本不是 运行 没有 sudo - 为什么?

python script is not running without sudo - why?

这是我的 python 脚本,它从我的 S3 存储桶中下载最新的图像。当我 运行 使用 sudo python script.py 这个脚本时,它按预期运行, 但不是当我 运行 它作为 python script.py。在这种情况下,脚本干净利落地完成,没有异常或进程锁定,但没有图像文件。

为什么会这样?我可以在 boto 的图书馆尽头做点什么吗?

import boto
import logging


def s3_download():
    bucket_name = 'cloudadic'
    conn = boto.connect_s3('XXXXXX', 'YYYYYYY')
    bucket = conn.get_bucket(bucket_name)

    for key in bucket.list('ocr/uploads'):
        try:
            l = [(k.last_modified, k) for k in bucket]
            key = sorted(l, cmp=lambda x, y: cmp(x[0], y[0]))[-1][1]
            res = key.get_contents_to_filename(key.name)
        except:
            logging.info(key.name + ":" + "FAILED")

if __name__ == "__main__":
     s3_download()

大概问题是您试图将内容存储在您的用户没有权限的地方。第二个问题是您的脚本隐藏了错误。 except 块完全忽略了发生的异常类型(当然会消耗它们,因此您永远看不到它们),并使用默认情况下不显示的 logging.info ;这可能至少应该是一个警告,如果它显示出了什么问题会更好。顺便说一下,您很可能不应该在此处发布 S3 身份验证密钥。

在 python 中开始开发之前,请始终安装 virtual environment

您遇到的问题是典型的python新手问题:使用sudo安装所有pypi包。

当您执行 sudo pip install boto3 时,它会将 pypi 包安装到系统工作区并且只能由 sudo 访问。在这种情况下,sudo python script.py 将起作用,因为它有权访问包。

为了解决这个问题和开发环境的隔离(这样你就不会用不同的 pypi 包污染不同的项目),python 开发人员将安装 python 虚拟环境(从上面 link), 然后使用 mkvirtualenv 创建你的项目工作区, 运行 pip installpython setup.py install 将所需的包安装到环境中,然后你可以 运行 python 没有 sudo python.

Python出于同样的原因,virtualenv 也部署在生产环境中。

重要提示:避免使用 boto 和 boto2。 AWS 不再支持它们,也不再修复错误(AWS 未正式支持 boto2,使用它需要您自担风险)。切换到 boto3。


对于异常处理问题,@Yann Vernier 已经提到了。 logging.info 不会记录异常错误。您可以尝试使用 logging.debug 或简单地使用 raise 来引发实际的异常错误。

@Nearoo 在评论中建议使用 except Exception as inst 来捕获异常。

像这样捕捉异常

except Exception as inst:
            print(type(inst))
            print(inst.args)
            print(inst)

如果脚本是使用 python 3x 编译的,应该会出现这个错误 如果您使用 python 2.7 编译脚本,则不会出现此错误。

可能您的系统上有多个版本的 python, 这应该是 python script.pysudo python script.py 行为差异的原因,并且对于相同的@mootmoot 答案建议使用 virtualenv

'cmp' is an invalid keyword argument for this function

现在,如果您搜索此错误,您应该会发现 cmp 已在 python 3x 中弃用,建议改用 key

添加这些导入

import functools
from functools import cmp_to_key

并替换 有了这些

key2 = sorted(l, key = cmp_to_key(lambda x,y: (x[0] > y[0]) - (x[0] < y[0])))[-1][1]
res = key2.get_contents_to_filename(key2.name)

(x[0] > y[0]) - (x[0] < y[0]) 替代 cmp(x[0], y[0])

cmp 替换为 key 并且 cmp_to_key 从 functools lib

中使用

Check this out