subprocess.Popen: 'OSError: [Errno 2] No such file or directory' only on Linux

我们两清 提交于 2019-12-12 04:39:29

问题


This is not a duplicate of subprocess.Popen: 'OSError: [Errno 13] Permission denied' only on Linux as that problem occurred due to wrong permissions. That has been fixed and this is an entirely different problem.

When my code (given below) executes on Windows (both my laptop and AppVeyor CI), it does what it's supposed to do. But on Linux (VM on TravisCI), it throws me a file not found error.

I am executing in /home/travis/build/sayak-brm/espeak4py/.

ls -l outputs:

$ ls -l
total 48
-rw-rw-r-- 1 travis travis   500 Sep 29 20:14 appveyor.yml
drwxrwxr-x 3 travis travis  4096 Sep 29 20:14 espeak4py
-rw-rw-r-- 1 travis travis 32400 Sep 29 20:14 LICENSE.md
-rw-rw-r-- 1 travis travis  2298 Sep 29 20:14 README.md
-rw-rw-r-- 1 travis travis     0 Sep 29 20:14 requirements.txt
-rw-rw-r-- 1 travis travis   759 Sep 29 20:14 test.py

$ ls -l espeak4py
total 592
-rwxr-xr-x 1 travis travis 276306 Sep 30 06:42 espeak
drwxrwxr-x 5 travis travis   4096 Sep 29 20:14 espeak-data
-rw-rw-r-- 1 travis travis 319488 Sep 29 20:14 espeak.exe
-rw-rw-r-- 1 travis travis   1125 Sep 29 20:14 __init__.py

$ ls -l /home/travis/build/sayak-brm/espeak4py/espeak4py
total 592
-rwxr-xr-x 1 travis travis 276306 Sep 30 06:42 espeak
drwxrwxr-x 5 travis travis   4096 Sep 30 06:42 espeak-data
-rw-rw-r-- 1 travis travis 319488 Sep 30 06:42 espeak.exe
-rw-rw-r-- 1 travis travis   1216 Sep 30 06:42 __init__.py

which shows that the files are where they are supposed to be.

The espeak file is a Linux ELF Binary.


Error:

$ python3 test.py
Testing espeak4py
Testing wait4prev
Traceback (most recent call last):
  File "test.py", line 10, in <module>
    mySpeaker.say('Hello, World!')
  File "/home/travis/build/sayak-brm/espeak4py/espeak4py/__init__.py", line 38, in say
    self.prevproc = subprocess.Popen(cmd, executable=self.executable, cwd=os.path.dirname(os.path.abspath(__file__)))
  File "/opt/python/3.2.6/lib/python3.2/subprocess.py", line 744, in __init__
    restore_signals, start_new_session)
  File "/opt/python/3.2.6/lib/python3.2/subprocess.py", line 1394, in _execute_child
    raise child_exception_type(errno_num, err_msg)
OSError: [Errno 2] No such file or directory: '/home/travis/build/sayak-brm/espeak4py/espeak4py/espeak'

Code:

espeak4py/__init__.py:

#! python3
import subprocess
import os
import platform

class Speaker:
    """
    Speaker class for differentiating different speech properties.
    """
    def __init__(self, voice="en", wpm=120, pitch=80):
        self.prevproc = None
        self.voice = voice
        self.wpm = wpm
        self.pitch = pitch
        if platform.system() == 'Windows': self.executable = os.path.dirname(os.path.abspath(__file__)) + "/espeak.exe"
        else: self.executable = os.path.dirname(os.path.abspath(__file__)) + "/espeak"

    def generateCommand(self, phrase):
        cmd = [
            self.executable,
            "--path=.",
            "-v", self.voice,
            "-p", self.pitch,
            "-s", self.wpm,
            phrase
        ]
        cmd = [str(x) for x in cmd]
        return cmd

    def say(self, phrase, wait4prev=False):
        cmd=self.generateCommand(phrase)
        if wait4prev:
            try: self.prevproc.wait()
            except AttributeError: pass
        else:
            try: self.prevproc.terminate()
            except AttributeError: pass
        self.prevproc = subprocess.Popen(cmd, executable=self.executable, cwd=os.path.dirname(os.path.abspath(__file__)))

test.py:

#! python3
import espeak4py
import time

print('Testing espeak4py\n')
print('Testing wait4prev')

mySpeaker = espeak4py.Speaker()

mySpeaker.say('Hello, World!')
time.sleep(1)
mySpeaker.say('Interrupted!')
time.sleep(3)

mySpeaker.say('Hello, World!')
time.sleep(1)
mySpeaker.say('Not Interrupted.', wait4prev=True)
time.sleep(5)

print('Testing pitch')

myHighPitchedSpeaker = espeak4py.Speaker(pitch=120)
myHighPitchedSpeaker.say('I am a demo of the say function')
time.sleep(5)

print('Testing wpm')

myFastSpeaker = espeak4py.Speaker(wpm=140)
myFastSpeaker.say('I am a demo of the say function')
time.sleep(5)

print('Testing voice')

mySpanishSpeaker = espeak4py.Speaker(voice='es')
mySpanishSpeaker.say('Hola. Como estas?')

print('Testing Completed.')

I don't understand why it works only on one platform and not the other.

Travis CI Logs: https://travis-ci.org/sayak-brm/espeak4py

AppVeyor Logs: https://ci.appveyor.com/project/sayak-brm/espeak4py

GitHub: https://sayak-brm.github.io/espeak4py


回答1:


I've tested your espeak Python wrapper on Linux, and it works for me. Probably it's just an issue with Windows trailing \r characters. You could try the following:

sed -i 's/^M//' espeak4py/__init__.py

To enter the ^M, type Ctrl-V followed by Ctrl-M, and see if running that sed command solves the issue.




回答2:


The Linux binary packaged with the repo is not compatible with the Travis Build Architecture and the binary needs t be built from source before it is executed.

Instructions for buiding: https://github.com/rhdunn/espeak#building-1



来源:https://stackoverflow.com/questions/39785140/subprocess-popen-oserror-errno-2-no-such-file-or-directory-only-on-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!