簡體   English   中英

os.execv(sys.executable) 使用了錯誤的 Python 版本

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM