案例解析
這個問題描述起來有點違反直覺,要執行一個文件難道不應該需要可執行權限嗎?讓我們先來看一個例子:
# module1.py
def test():
print ('hello world!')
if __name__ == '__main__':
test()
這是一個名為module1.py
的文件,這個文件僅有可讀權限:
[dechin@dechin-manjaro excute]$ ll
-r--r--r-- 1 dechin dechin 78 1月 15 17:06 module1.py
我們可以直接用python來運行一下這個文件:
[dechin@dechin-manjaro excute]$ python3 module1.py
hello world!
我們發現即使只有可讀權限,這個文件也是可以運行的。為了嚴格驗證,我們這里創建另外一種模式的測試,通過import來導入python文件,是否也不需要可執行權限呢?
# module2.py
from module1 import test
if __name__ == '__main__':
test()
同樣的,我們新建的文件也未賦予可執行權限:
[dechin@dechin-manjaro excute]$ ll
-r--r--r-- 1 dechin dechin 78 1月 15 17:06 module1.py
-r--r--r-- 1 dechin dechin 64 1月 15 17:44 module2.py
我們執行一下module2.py
這個文件:
[dechin@dechin-manjaro excute]$ python3 module2.py
hello world!
那么我們的測試就完成了,經過驗證,執行普通的py文件是不需要可執行權限的,這對我們的權限最小化約束就產生了一定的啟發作用。
原理解釋
在stackoverrun上面有一條回復,作者cedbeu是這樣描述的:python
本身承擔了語言解析器的角色,py文件
不過是一個文本文件,真正執行的二進制文件是python
而不是用戶所創建的py文件
。因此,即使去掉py文件
的可執行權限,該py文件
也是可以通過python來執行的。但是,如果我們去掉了python
的可執行權限,那就無法正常執行這一條任務了。
擴展測試
如果將py文件
編譯成pyc
和pyo
格式的文件,此時的任務執行是否需要可執行權限呢?首先測試pyc文件
:
[dechin@dechin-manjaro excute]$ python3 -m py_compile module1.py
執行完編譯,我們會在當前目錄下發現一個__pycache__
的文件夾,編譯好的pyc文件
就存儲在這個目錄下:
[dechin@dechin-manjaro excute]$ tree
.
├── module1.py
├── module2.py
└── __pycache__
└── module1.cpython-38.pyc
1 directory, 3 files
[dechin@dechin-manjaro excute]$ cd __pycache__/
[dechin@dechin-manjaro __pycache__]$ ll
總用量 4
-rw-r--r-- 1 dechin dechin 259 1月 15 18:01 module1.cpython-38.pyc
這里我們看到pyc文件
的文件名會固定有個后綴,同樣也沒有可執行權限,這里我們用同樣的命令來執行pyc文件
:
[dechin@dechin-manjaro __pycache__]$ ll
-r--r--r-- 1 dechin dechin 259 1月 15 18:01 module1.cpython-38.pyc
-rw-r--r-- 1 dechin dechin 259 1月 15 18:13 module1.pyc
-r--r--r-- 1 dechin dechin 64 1月 15 18:09 module2.py
[dechin@dechin-manjaro __pycache__]$ python3 module1.cpython-38.pyc
hello world!
[dechin@dechin-manjaro __pycache__]$ python3 module2.py
hello world!
這里我們可以發現,不論是直接執行pyc文件
,或者是改名為module1.pyc
之后再通過module2.py
導入的方式,都可以正常的被執行,而且都不具有可執行權限。接下來我們再嘗試一下pyo文件:
[dechin@dechin-manjaro excute]$ python3 -O -m py_compile module1.py
執行帶有opt
的pyc文件
:
[dechin@dechin-manjaro __pycache__]$ python3 module1.cpython-38.opt-1.pyc
hello world!
同樣的,都可以正常的被執行,即使沒有可執行權限。
技術彩蛋
即使我們把pyc文件
強行改名為py文件
,同樣也是不影響任務執行的:
[dechin@dechin-manjaro __pycache__]$ cp module1.cpython-38.opt-1.pyc module1.py
[dechin@dechin-manjaro __pycache__]$ ll
總用量 20
-rw-r--r-- 1 dechin dechin 259 1月 15 18:17 module1.cpython-38.opt-1.pyc
-r--r--r-- 1 dechin dechin 259 1月 15 18:01 module1.cpython-38.pyc
-rw-r--r-- 1 dechin dechin 259 1月 15 18:20 module1.py
-rw-r--r-- 1 dechin dechin 259 1月 15 18:13 module1.pyc
-r--r--r-- 1 dechin dechin 64 1月 15 18:09 module2.py
[dechin@dechin-manjaro __pycache__]$ python3 module1.py
hello world!
在后續的文章中,我會專門寫一篇文章,分析如何分辨py文件
與改名之后的pyc文件
。
版權聲明
本文首發鏈接為:https://www.cnblogs.com/dechinphy/p/excutable.html
作者ID:DechinPhy
更多原著文章請參考:https://www.cnblogs.com/dechinphy/