簡體   English   中英

為什么Python命令“subprocess.Popen”找不到要運行的jar文件?

[英]Why can't the Python command "subprocess.Popen" find the jar file to run?

我正在嘗試從這個 repo 運行代碼: https : //github.com/tylin/coco-caption ,特別是來自https://github.com/tylin/coco-caption/blob/master/pycocoevalcap/tokenizer/ptbtokenizer .py ,第 51-52 行:

p_tokenizer = subprocess.Popen(cmd, cwd=path_to_jar_dirname, \
            stdout=subprocess.PIPE)

我運行的錯誤是

OSError: [Errno 2] No such file or directory

我無法弄清楚為什么找不到該文件。

我試圖運行的罐子是:

stanford-corenlp-3.4.1.jar

您可以通過轉到https://github.com/tylin/coco-caption/tree/master/pycocoevalcap/tokenizer查看目錄結構。 當我運行代碼行時,為了更具體地了解我的實際參數是什么:

cmd= ['java', '-cp', 'stanford-corenlp-3.4.1.jar', 'edu.stanford.nlp.process.PTBTokenizer', '-preserveLines', '-lowerCase', 'tmpWS5p0Z'],

path_to_dirname =abs_path_to_folder/tokenizer

我可以看到需要運行的jar,而且它看起來在正確的位置,為什么python找不到它。 (注意:我使用的是 python2.7。)臨時文件 'tmpWS5p0Z' 是它應該在的位置。

編輯:我正在使用 Ubuntu

以防萬一它可能對某人有所幫助:

我正在努力解決同樣的問題(相同的https://github.com/tylin/coco-caption代碼)。 可以說我在 CentOS 上使用qsub運行帶有 python 3.7 的代碼。 所以我改變了

cmd = ['java', '-cp', 'stanford-corenlp-3.4.1.jar', 'edu.stanford.nlp.process.PTBTokenizer', '-preserveLines', '-lowerCase', 'tmpWS5p0Z']

cmd = ['/abs/path/to/java -cp /abs/path/to/stanford-corenlp-3.4.1.jar edu.stanford.nlp.process.PTBTokenizer -preserveLines -lowerCase ', ' /abs/path/to/temporary_file']

使用絕對路徑修復了OSError: [Errno 2] No such file or directory 請注意,我仍然將'/abs/path/to/temporary_file'作為cmd列表中的第二個元素,因為它是稍后添加的。 但是后來在標記器 java 子進程中出了點問題,我不知道為什么或什么,只是觀察,因為:

p_tokenizer = subprocess.Popen(cmd, cwd=path_to_jar_dirname, stdout=subprocess.PIPE, shell=True)
token_lines = p_tokenizer.communicate(input=sentences.rstrip())[0]

這里token_lines是一個空列表(這不是想要的行為)。 在 IPython 中執行它會產生以下結果(只是subprocess.Popen(... ,而不是communicate )。

Exception in thread "main" edu.stanford.nlp.io.RuntimeIOException: java.io.IOException: Input/output error
    at edu.stanford.nlp.process.PTBTokenizer.getNext(PTBTokenizer.java:278)
    at edu.stanford.nlp.process.PTBTokenizer.getNext(PTBTokenizer.java:163)
    at edu.stanford.nlp.process.AbstractTokenizer.hasNext(AbstractTokenizer.java:55)
    at edu.stanford.nlp.process.PTBTokenizer.tokReader(PTBTokenizer.java:444)
    at edu.stanford.nlp.process.PTBTokenizer.tok(PTBTokenizer.java:416)
        at edu.stanford.nlp.process.PTBTokenizer.main(PTBTokenizer.java:760)
Caused by: java.io.IOException: Input/output error
    at java.base/java.io.FileInputStream.readBytes(Native Method)
    at java.base/java.io.FileInputStream.read(FileInputStream.java:279)
    at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:290)
    at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:351)
    at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185)
    at java.base/java.io.BufferedReader.read1(BufferedReader.java:210)
    at java.base/java.io.BufferedReader.read(BufferedReader.java:287)
    at edu.stanford.nlp.process.PTBLexer.zzRefill(PTBLexer.java:24511)
    at edu.stanford.nlp.process.PTBLexer.next(PTBLexer.java:24718)
    at edu.stanford.nlp.process.PTBTokenizer.getNext(PTBTokenizer.java:276)
    ... 5 more

同樣,我不知道為什么或什么,但我只是想分享一下,這樣做修復了它:

cmd = ['/abs/path/to/java -cp /abs/path/to/stanford-corenlp-3.4.1.jar edu.stanford.nlp.process.PTBTokenizer -preserveLines -lowerCase /abs/path/to/temporary_file']

並將cmd.append(os.path.join(path_to_jar_dirname, os.path.basename(tmp_file.name)))cmd[0] += os.path.join(path_to_jar_dirname, os.path.basename(tmp_file.name))

所以將cmd變成一個只有 1 個元素的列表,一次包含整個命令和絕對路徑。 謝謝你的幫助!

嘗試絕對路徑(意思是從根/開始的路徑)

https://en.wikipedia.org/wiki/Path_(computing)#Absolute_and_relative_paths

對於 Python 中的相對路徑,請參見 ie Python 中的相對路徑如何在 Python 中使用代碼存儲庫時引用資源的相對路徑

更新:

作為測試,使用shell=True選項嘗試subprocess.Popen()並為任何涉及的文件提供絕對路徑,包括tmpWS5p0Z

在這個subprocess.Popen()調用中涉及兩條路徑:

1)python路徑,python必須找到java可執行文件和stanford-corenlp-3.4.1.jar ,它本質上是一個有自己路徑的java程序

2) stanford-corenlp-3.4.1.jar的java路徑

因為這太復雜了嘗試

p_tokenizer = subprocess.Popen(['/absolute_path_to/java -cp /absolute_path_to/stanford-corenlp-3.4.1.jar /absolute_path_to/edu.stanford.nlp.process.PTBTokenizer -preserveLines -lowerCase /absolute_path_to/tmpWS5p0Z' ], shell=True)

Python 通過參數指定 popen 工作目錄

Python subprocess.Popen() 錯誤(沒有那個文件或目錄)

正如@Lars 上面提到的,我遇到的問題是我沒有安裝 Java。 解決了它:

sudo apt update    
sudo apt install default-jdk
sudo apt install default-jre

發表這篇文章是因為我兩次遇到這個問題(由於重新安裝問題)並忘記了它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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