Python-эквивалент операторов Perl для чтения файлов (-r), записи (-w) и выполнения (-x) - PullRequest
11 голосов
/ 19 декабря 2010

Я пытался найти и найти в Python эквивалент некоторых операторов Perl для проверки файлов.

Большинство операторов проверки файлов являются просто прямым Pythonification основного вызова os 'stat.Например, os.stat('file').st_ctime просто считывает время смены инода, как это делает утилита * nix stat или ls -l.

Некоторые операторы тестирования файла Perl, я не могу найти эквивалент в Python.Например, у меня есть дерево данных с 85 000 файлов изображений, созданных различными приложениями.У некоторых файлов эффективный UID установлен таким образом, что это не очень полезно, и изменение не удается из-за проблем с разрешениями.Поэтому для этих файлов мне нужно запустить что-то вроде:

$ find . -type f -print0 | perl -0 -lnE 'say unless -w' | change euid...

Так как я не нашел эквивалент в Python, я должен выложить в Perl, чтобы найти эти файлы.Я нашел эту таблицу , которая предполагает, что нет прямого эквивалента.Правда?

Ответы [ 4 ]

10 голосов
/ 19 декабря 2010

Глядя на вывод strace, perl выполняет вызов stat(), за которым следует getgroups(), чтобы получить идентификаторы дополнительных групп процесса perl.Похоже, он просто проверяет результаты вызова stat() по EUID, EGID и дополнительным идентификаторам групп.

Python имеет функцию getgroups() в os, поэтому я уверен, что вы могли быто же самое.

РЕДАКТИРОВАТЬ: Вы можете попробовать что-то вроде этого, если никто не придумал лучшего ответа.(С трудом проверено):

def effectively_readable(path):
    import os, stat

    uid = os.getuid()
    euid = os.geteuid()
    gid = os.getgid()
    egid = os.getegid()

    # This is probably true most of the time, so just let os.access()
    # handle it.  Avoids potential bugs in the rest of this function.
    if uid == euid and gid == egid:
        return os.access(path, os.R_OK)

    st = os.stat(path)

    # This may be wrong depending on the semantics of your OS.
    # i.e. if the file is -------r--, does the owner have access or not?
    if st.st_uid == euid:
        return st.st_mode & stat.S_IRUSR != 0

    # See comment for UID check above.
    groups = os.getgroups()
    if st.st_gid == egid or st.st_gid in groups:
        return st.st_mode & stat.S_IRGRP != 0

    return st.st_mode & stat.S_IROTH != 0

Очевидно, что -w будет почти идентичным, но с W_OK, S_IWUSR и т. Д.

5 голосов
/ 27 марта 2013

Начиная с Python 3.3, вы можете сделать это с помощью os.access:

Изменено в версии 3.3: добавлены параметры dir_fd ,ffective_ids и follow_symlinks.

Если значение active_ids равно True, access () выполнит свои проверки доступа, используя действительный uid / gid вместо реального uid / gid.ffective_ids может не поддерживаться на вашей платформе;Вы можете проверить, доступен ли он, используя os.supports_effective_ids.Если он недоступен, его использование вызовет NotImplementedError.

1 голос
/ 19 декабря 2010

os.access делает именно то, что вы хотите.

Используйте реальный uid / gid для проверки доступа к path .Обратите внимание, что в большинстве операций используется эффективный uid / gid, поэтому эту процедуру можно использовать в среде suid / sgid для проверки, имеет ли вызывающий пользователь указанный доступ к path .

1 голос
/ 19 декабря 2010

Чтобы проверить, может ли ваш эффективный пользователь записать файл, большинство просто откроет его и попытается обнаружить ошибку в исключении.Может не быть правильным решением во всех случаях, но объясняет, почему для этого нет конкретной поддержки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...