คุณจะทำ“ chmod + x” ง่ายๆจากภายใน python ได้อย่างไร?


120

ฉันต้องการสร้างไฟล์จากภายในสคริปต์ python ที่สามารถเรียกใช้งานได้

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

ดูเหมือนว่าos.chmodจะไม่ 'เพิ่ม' การอนุญาตแบบที่ยูนิกซ์chmodทำ ด้วยบรรทัดสุดท้ายออกความเห็นไฟล์มี filemode กับมันไม่ได้ออกความเห็นโหมดไฟล์เป็น-rw-r--r-- ---x------ฉันจะเพิ่มu+xค่าสถานะในขณะที่ยังคงโหมดที่เหลืออยู่ได้อย่างไร

คำตอบ:


198

ใช้os.stat()เพื่อรับสิทธิ์ปัจจุบันใช้|กับหรือบิตร่วมกันและใช้os.chmod()เพื่อตั้งค่าการอนุญาตที่อัปเดต

ตัวอย่าง:

import os
import stat

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

2
สิ่งนี้ทำให้สามารถดำเนินการได้โดยผู้ใช้เท่านั้น ผู้โพสต์ถามเกี่ยวกับ "chmod + x" ซึ่งทำให้สามารถดำเนินการได้ทั่วทั้งกระดาน (ผู้ใช้กลุ่มโลก)
eric.frederich

35
ใช้สิ่งต่อไปนี้เพื่อให้ทุกคนสามารถใช้งานได้ ... stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH หมายเหตุ: ค่านั้นเหมือนกับ 0111 ฐานแปดดังนั้นคุณสามารถทำได้ st.st_mode | 0111
eric.frederich

1
คำตอบของฉันด้านล่างคัดลอกบิต R เป็น X ตามที่คาดหวังจากคอมไพเลอร์
Jonathon Reinhart

ฉันจะทำSTAT_OWNER_EXECUTABLE = stat.S_IEXECและใช้ค่าคงที่ในท้องถิ่นที่มนุษย์อ่านได้แทนค่าที่พูดพล่อยๆ
ThorSummoner

นี่เป็นคำตอบที่ไม่ pythonic ที่อาจจะเล็ก ๆ น้อย ๆ ที่สามารถอ่านเพิ่มเติมได้ที่: และขอให้คุณได้ง่ายขึ้นที่จะดำเนินการเช่นsubprocess.check_call(['chmod', '+x', 'somefile']) a+rx
Trevor Boyd Smith

20

สำหรับเครื่องมือที่สร้างไฟล์ปฏิบัติการ (เช่นสคริปต์) รหัสต่อไปนี้อาจเป็นประโยชน์:

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

สิ่งนี้ทำให้ (มากหรือน้อย) เคารพสิ่งumaskที่มีผลเมื่อสร้างไฟล์: Executable ถูกตั้งค่าสำหรับไฟล์ที่อ่านได้เท่านั้น

การใช้งาน:

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 แทนคุณ0444จะใช้0o444. 292หรือถ้าคุณต้องการที่จะสนับสนุนทั้งสองเพียงแค่เขียน
Kevin

1
@ เควินดูเหมือนว่าไวยากรณ์ใหม่ได้รับการสนับสนุนโดย Python 2.6 ดังนั้นจึงดูสมเหตุสมผลที่จะใช้สิ่งนั้น (สำหรับจุดอ้างอิงความเข้ากันได้ CentOS 6 จะมาพร้อมกับ Python 2.6)
Jonathon Reinhart

2
ฉันไม่รู้ว่า Python 3 ได้ลบตัวอักษรฐานแปดแบบดั้งเดิม ขอบคุณสำหรับสิ่งนั้น
Jonathon Reinhart

13

หากคุณทราบสิทธิ์ที่คุณต้องการตัวอย่างต่อไปนี้อาจเป็นวิธีที่ง่าย

Python 2:

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

Python 3:

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

เข้ากันได้กับ (การแปลงฐานแปด):

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

ตัวอย่างสิทธิ์การอ้างอิง


4
ควรเป็น os.chmod ("/ somedir / somefile", 0o775)
ang mo

4

คุณยังสามารถทำได้

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

รายชื่อไฟล์ปัจจุบัน

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

ตอนนี้ทำสิ่งนี้

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

และคุณจะเห็นสิ่งนี้ในเทอร์มินัล

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

คุณสามารถใช้บิตหรือ 0o111 เพื่อทำให้ไฟล์ปฏิบัติการทั้งหมด 0o222 ทำให้เขียนได้ทั้งหมดและ 0o444 เพื่อให้อ่านได้ทั้งหมด


2

เคารพumaskเช่นchmod +x

man chmodบอกว่าถ้าaugoไม่ได้รับใน:

chmod +x mypath

จากนั้นaจะใช้ แต่กับumask:

การรวมกันของตัวอักษร ugoa ควบคุมการเข้าถึงไฟล์ของผู้ใช้ที่จะเปลี่ยนแปลง: ผู้ใช้ที่เป็นเจ้าของไฟล์ (u) ผู้ใช้รายอื่นในกลุ่มของไฟล์ (g) ผู้ใช้อื่นที่ไม่อยู่ในกลุ่มของไฟล์ (o) หรือทั้งหมด ผู้ใช้ (ก) หากไม่ได้รับสิ่งเหล่านี้เอฟเฟกต์จะเหมือนกับว่า (a) ได้รับแต่บิตที่ตั้งค่าใน umask จะไม่ได้รับผลกระทบ

นี่คือเวอร์ชันที่จำลองพฤติกรรมดังกล่าว:

#!/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')

ดูเพิ่มเติม: ฉันจะรับสิทธิ์ไฟล์เริ่มต้นใน Python ได้อย่างไร

ทดสอบใน Ubuntu 16.04, Python 3.5.2


1

ใน python3:

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

อย่าลืมเพิ่ม0oคำนำหน้าเนื่องจากสิทธิ์ถูกตั้งค่าเป็นจำนวนเต็มฐานแปดและ Python จะถือว่าจำนวนเต็มใด ๆ ที่มีศูนย์นำหน้าเป็นฐานแปดโดยอัตโนมัติ มิฉะนั้นคุณจะผ่านแน่นอนซึ่งเป็นฐานแปดของos.chmod("somefile", 1230)664


1
สิ่งนี้จะตั้งค่าการอนุญาตเป็นค่าสัมบูรณ์ แต่จะไม่ทำchmod +ตามที่ OP ขอซึ่งควรเพิ่มสิทธิ์ใหม่ให้กับสิทธิ์ที่มีอยู่
Ciro Santilli 郝海东冠状病六四事件法轮功

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.