代码之家  ›  专栏  ›  技术社区  ›  lars

为什么Python命令“subprocess.Popen”无法找到要运行的jar文件?

  •  4
  • lars  · 技术社区  · 7 年前

    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”应该在这里。

    3 回复  |  直到 7 年前
        1
  •  3
  •   ralf htp    7 年前

    尝试 完全的 / )

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

    有关python中的相对路径,请参见。 Relative paths in Python , How to refer to relative paths of resources when working with a code repository in Python

    更新:

    作为测试尝试 subprocess.Popen() shell=True 选项并为任何涉及的文件提供绝对路径,包括 tmpWS5p0Z

    在这个 呼叫涉及两条路径:

    1) python路径,python必须找到 java 可执行文件和 stanford-corenlp-3.4.1.jar

    因为这太复杂了试一下

    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 specify popen working directory via argument

    Python subprocess.Popen() error (No such file or directory)

        2
  •  3
  •   rubencart    5 年前

    以防万一,它可能会帮助某人:

    我在努力解决同样的问题(同样 https://github.com/tylin/coco-caption 代码)。可以这样说,我在CentOS上使用python 3.7运行代码 qsub

    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)) .

    所以制造 命令

        3
  •  0
  •   jps    2 年前

    正如@Lars在上面提到的,我遇到的问题是没有安装Java。解决方法:

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

    这篇文章,因为我有这个问题两次(由于重新安装问题),并忘记了它。