[英]os.execv(sys.executable) uses wrong Python version
我想從內部重新啟動腳本。 但是在 Linux 上os.execv
忽略sys.executable
並回退到默認的 Python 版本 2.7。
這是一個最小的運行示例:
import os
import sys
print(sys.executable, sys.version)
os.execv(sys.executable, ["python"] + sys.argv)
這是python3 main.py
的輸出(python3 指的是默認的 python 3 exe):
> /usr/local/bin/python3.8 3.8.0 (default, Jun 1 2022, 16:03:28) [GCC 8.3.0]
> /usr/bin/python 3.8.0 (default, Jun 1 2022, 16:03:28) [GCC 8.3.0]
> ('/usr/bin/python', '2.7.16 (default, Oct 10 2019, 22:02:15) \n[GCC 8.3.0]')
> ('/usr/bin/python', '2.7.16 (default, Oct 10 2019, 22:02:15) \n[GCC 8.3.0]')
> ('/usr/bin/python', '2.7.16 (default, Oct 10 2019, 22:02:15) \n[GCC 8.3.0]')
...
我不太明白需要更改哪些部分或出了什么問題/我做錯了什么。
execv()
中 Python 版本的顯式規范不會像僅python
的規范那樣導致回退到 Python 2 版本。 查看代碼(未執行無限循環):
import os, sys, time
strF = None
try:
f = open("counter.txt", "r")
strF = f.read()
f.close()
except:
print('except')
f = open("counter.txt", "w")
f.write("0")
f.close()
strF = "0"
if strF == '3':
print('> strF == 3')
sys.exit()
print('>> strF == 3')
else:
f = open("counter.txt", "w")
f.write(str(1+int(strF)))
f.close()
print(sys.executable, sys.version, strF)
time.sleep(3)
os.execv(sys.executable, ["python3.9"] + sys.argv)
這給出了以下輸出:
$ python3.9 main.py
except
/usr/local/bin/python3.9 3.9.13 (main, May 20 2022, 21:21:14)
[GCC 5.4.1 20160904] 0
/usr/local/bin/python3.9 3.9.13 (main, May 20 2022, 21:21:14)
[GCC 5.4.1 20160904] 1
/usr/local/bin/python3.9 3.9.13 (main, May 20 2022, 21:21:14)
[GCC 5.4.1 20160904] 2
> strF == 3
如果未指定 Python 版本,則輸出為:
$ python3.9 main.py
except
/usr/local/bin/python3.9 3.9.13 (main, May 20 2022, 21:21:14)
[GCC 5.4.1 20160904] 0
/usr/bin/python 3.9.13 (main, May 20 2022, 21:21:14)
[GCC 5.4.1 20160904] 1
('/usr/bin/python', '2.7.12 (default, Nov 19 2016, 06:48:10) \n[GCC 5.4.0 20160609]', '2')
> strF == 3
更新(1): execv()
從自身內部重新啟動腳本的唯一正確用法應該是:
os.execv(sys.executable, [sys.executable] + sys.argv)
使用上面的代碼,不需要明確指定 Python 版本,因此它應該適用於任何 Python 版本,因為版本不能是硬編碼的。
Python 文檔( https://docs.python.org/3/library/os.html?highlight=execv#os.execv )在我看來並沒有充分解釋os.execv()
的實際作用,因為它給出了相同的值兩次顯得有些奇怪。 也許其他人可以在這里對此發表評論? os.execv(path, args)
path
的路徑實際上是什么意思?
Python 文檔僅聲明:
當參數的數量是可變的時,[exec()] 的“v”變體很好,參數在列表或元組中作為 args 參數傳遞。 在任何一種情況下,子進程的參數都應該以正在運行的命令的名稱開頭,但這不是強制的。
更新(2):正如評論中指出的那樣,python3 調用 python2 的方式不是在第一次,而是在第二次重新啟動時似乎如下:
盡管 python3 使用 argv[0] 'python' 值作為重新啟動的 Python 腳本運行中的 sys.executable,但它實際上執行了 in 'path' (是否稱為 ""path"" 以增加混淆???)參數到 execv() 通過 python3. 現在在 main.py 的重新啟動版本中,sys.executable 值是錯誤的,不反映運行腳本的 Python 版本導致運行 python2(如果 python2 是系統上的默認 python 版本)作為可執行文件僅在第二次重啟。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.