16

在 Mac OS 上使用 python,我想打开一个文件进行写入并将一些 shell 命令放入其中。稍后在终端中运行。

with open("my_script.sh", "w") as fd:
    fd.write("#!/bin/sh\n")
    fd.write("echo $PATH\n")

这将创建文件,但我不知道如何设置执行位,所以当我在终端中运行它时,我不会得到:

sh: my_script.sh: Permission denied
4

2 回答 2

23
import os
os.chmod("my_script.sh", 0744)

不过,请正确选择值。有些值可能不安全。

于 2012-12-31T18:10:21.663 回答
13

您始终可以在终端 shell 中执行此操作,然后再运行它,使用chmod

chmod a+x my_script.sh

如果您想从 Python 中执行此操作,您可以使用其中之一chmodfchmodos模块中使用。既然你已经打开了文件,我会做后者:

with open("my_script.sh", "w") as fd:
    fd.write("#!/bin/sh\n")
    fd.write("echo $PATH\n")
    os.fchmod(fd.fileno(), stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH | stat.S_IXOTH)

不幸的是,正如您所看到的,没有直接等同于为每个人chmod a+x添加x标志而将其他所有内容都放在一边。chmod但是您可以执行命令行工具实际执行的相同操作:stat文件(或在本例中fstat为 )获取现有权限,然后修改它们:

with open("my_script.sh", "w") as fd:
    fd.write("#!/bin/sh\n")
    fd.write("echo $PATH\n")
    mode = os.fstat(fd.fileno()).st_mode
    mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
    os.fchmod(fd.fileno(), stat.S_IMODE(mode))

S_IMODE(在大多数平台上,您实际上并不需要该步骤,因为要么st_mode没有任何额外的位,要么 (f)chmod无害地忽略它们——就像 OS X 那样。但最好做正确的事情,使您的代码可移植并且面向未来。)

大多数人认为“友好”的名字S_IXUSR并不是特别友好,一旦你学会用八进制来考虑模式,它实际上比试图记住 POSIX 如何缩写事物更容易,所以你可能更喜欢这个:

with open("my_script.sh", "w") as fd:
    fd.write("#!/bin/sh\n")
    fd.write("echo $PATH\n")
    mode = os.fstat(fd.fileno()).st_mode
    mode |= 0o111
    os.fchmod(fd.fileno(), mode & 0o7777)

111表示可由用户、组和其他人执行(与各个位相同)|ST_IX*并且7777是您被允许传递给 (f)的所有位chmod(与此相同S_IMODE)。

于 2012-12-31T19:47:44.460 回答