Python içinden basit bir "chmod + x" nasıl yapılır?


120

Çalıştırılabilir bir python betiğinden bir dosya oluşturmak istiyorum.

import os
import stat
os.chmod('somefile', stat.S_IEXEC)

os.chmodUnix'in chmodyaptığı gibi izinleri 'eklemiyor' görünüyor . Son satırın açıklamasıyla, dosyanın -rw-r--r--dosya modu vardır, açıklama yapılmamışsa dosya modu olur ---x------. u+xGeri kalan modları olduğu gibi tutarken bayrağı nasıl ekleyebilirim ?

Yanıtlar:


198

Kullanım os.stat()cari izinleri, kullanımını elde etmek için |birlikte veya bitleri ve kullanım os.chmod()güncellenen izinlerini ayarlamak için.

Misal:

import os
import stat

st = os.stat('somefile')
os.chmod('somefile', st.st_mode | stat.S_IEXEC)

2
Bu, yalnızca kullanıcı tarafından çalıştırılabilir hale getirir. Poster, panoda çalıştırılabilir kılan "chmod + x" hakkında sorular soruyordu (kullanıcı, grup, dünya)
eric.frederich

35
Bunu herkes tarafından yürütülebilir hale getirmek için aşağıdakileri kullanın ... stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH. Not: bu değer sekizlik 0111 ile aynıdır, bu nedenle sadece st.st_mode | 0111
eric.frederich

1
Aşağıdaki cevabım , bir derleyiciden beklendiği gibi, R bitlerini X'e kopyalar.
Jonathon Reinhart

Ben yapacağını STAT_OWNER_EXECUTABLE = stat.S_IEXECve anlamsız birinin yerine insan okunabilir yerel sabit kullanın.
ThorSummoner

İşte biraz daha okunaklı olabilecek pitonik olmayan bir cevap: subprocess.check_call(['chmod', '+x', 'somefile'])ve benzeri işlemleri daha kolay yapalım a+rx.
Trevor Boyd Smith

20

Yürütülebilir dosyalar (örn. Komut dosyaları) oluşturan araçlar için aşağıdaki kod yardımcı olabilir:

def make_executable(path):
    mode = os.stat(path).st_mode
    mode |= (mode & 0o444) >> 2    # copy R bits to X
    os.chmod(path, mode)

Bu umask, dosya yaratıldığında yürürlükte olana (aşağı yukarı) saygı duymasını sağlar : Yürütülebilir sadece okuyabilenler için ayarlanır.

Kullanımı:

path = 'foo.sh'
with open(path, 'w') as f:           # umask in effect when file is created
    f.write('#!/bin/sh\n')
    f.write('echo "hello world"\n')

make_executable(path)

2
Python 3'te sekizlik değişmezler değişti. Bunun yerine 0444kullanırsınız 0o444. Ya da her ikisini de desteklemek istiyorsanız yazın 292.
Kevin

1
@Kevin Görünüşe göre yeni sözdizimi Python 2.6 tarafından destekleniyor, dolayısıyla bunu kullanmak mantıklı görünüyor. (Uyumluluk referans noktası için CentOS 6, Python 2.6 ile birlikte gelir).
Jonathon Reinhart

2
Python 3'ün geleneksel sekizlik değişmezleri kaldırdığının farkında değildim. Bunun için teşekkür ederim.
Jonathon Reinhart

13

İstediğiniz izinleri biliyorsanız, aşağıdaki örnek bunu basit tutmanın yolu olabilir.

Python 2:

os.chmod("/somedir/somefile", 0775)

Python 3:

os.chmod("/somedir/somefile", 0o775)

Her ikisiyle de uyumlu (sekizlik dönüşüm):

os.chmod("/somedir/somefile", 509)

referans izin örnekleri


4
Bu os.chmod ("/ somedir / somefile", 0o775) olmalıdır
ang ay

4

Bunu da yapabilirsin

>>> import os
>>> st = os.stat("hello.txt")

Dosyanın mevcut listesi

$ ls -l hello.txt
-rw-r--r--  1 morrison  staff  17 Jan 13  2014 hello.txt

Şimdi yap bunu.

>>> os.chmod("hello.txt", st.st_mode | 0o111)

ve bunu terminalde göreceksiniz.

ls -l hello.txt    
-rwxr-xr-x  1 morrison  staff  17 Jan 13  2014 hello.txt

Bitsel olarak veya 0o111 ile tümü yürütülebilir yapmak için, 0o222 ile yazılabilir yapmak için ve 0o444 ile tümü okunabilir hale getirebilirsiniz.


2

umaskGibi saygıchmod +x

man chmoddiyor ki eğer augogibi verilmez:

chmod +x mypath

sonra akullanılır, ancak şu şekilde kullanılır umask:

Ugoa harflerinin bir kombinasyonu, hangi kullanıcıların dosyaya erişiminin değiştirileceğini kontrol eder: dosyanın sahibi olan kullanıcı (u), dosyanın grubundaki diğer kullanıcılar (g), dosyanın grubunda olmayan diğer kullanıcılar (o) veya tümü kullanıcılar (a). Bunlardan hiçbiri verilmemişse, etki (a) verilmiş gibidir, ancak umask'de ayarlanan bitler etkilenmez.

İşte bu davranışı tam olarak simüle eden bir sürüm:

#!/usr/bin/env python3

import os
import stat

def get_umask():
    umask = os.umask(0)
    os.umask(umask)
    return umask

def chmod_plus_x(path):
    os.chmod(
        path,
        os.stat(path).st_mode |
        (
            (
                stat.S_IXUSR |
                stat.S_IXGRP |
                stat.S_IXOTH
            )
            & ~get_umask()
        )
    )

chmod_plus_x('.gitignore')

Ayrıca bkz: Python'da varsayılan dosya izinlerini nasıl alabilirim?

Ubuntu 16.04, Python 3.5.2'de test edilmiştir.


1

Python3'te:

import os
os.chmod("somefile", 0o664)

0oİzinler sekizlik bir tamsayı olarak ayarlandığından ve Python otomatik olarak başında sıfır olan tüm tam sayıları sekizlik olarak ele aldığından öneki eklemeyi unutmayın . Aksi takdirde, os.chmod("somefile", 1230)sekizlik olan gerçekten geçiyorsunuz 664.


1
Bu, izinleri mutlak bir değere ayarlar, chmod +OP tarafından istendiği gibi yapmaz ve mevcut olanlara yeni izinler eklemelidir.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.