subprocess.Popen: 'OSError: [Errno 2] No such file or directory' only on Linux
<blockquote>
  <p>This is not a duplicate of <a href="http://stackoverflow.com/questions/39777345/subprocess-popen-oserror-errno-13-permission-denied-only-on-linux">subprocess.Popen: &#39;OSError: [Errno 13] Permission denied&#39; only on Linux</a> as that problem occurred due to wrong permissions. That has been fixed and this is an entirely different problem.</p>
</blockquote>

<p>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.</p>

<p>I am executing in <code>/home/travis/build/sayak-brm/espeak4py/</code>.</p>

<p><code>ls -l</code> outputs:</p>

<pre><code>$ 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
</code></pre>

<p>which shows that the files are where they are supposed to be.</p>

<p>The <code>espeak</code> file is a Linux ELF Binary.</p>

<hr>

<p><strong>Error:</strong></p>

<pre><code>$ python3 test.py
Testing espeak4py
Testing wait4prev
Traceback (most recent call last):
  File "test.py", line 10, in &lt;module&gt;
    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></pre>

<hr>

<p><strong>Code:</strong></p>

<p><code>espeak4py/__init__.py</code>:</p>

<pre><code>#! 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__)))
</code></pre>

<p><code>test.py</code>:</p>

<pre><code>#! 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.')
</code></pre>

<hr>

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

<p>Travis CI Logs: <a href="https://travis-ci.org/sayak-brm/espeak4py" rel="nofollow">https://travis-ci.org/sayak-brm/espeak4py</a></p>

<p>AppVeyor Logs: <a href="https://ci.appveyor.com/project/sayak-brm/espeak4py" rel="nofollow">https://ci.appveyor.com/project/sayak-brm/espeak4py</a></p>

<p>GitHub: <a href="https://sayak-brm.github.io/espeak4py" rel="nofollow">https://sayak-brm.github.io/espeak4py</a></p>

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

<pre><code>sed -i 's/^M//' espeak4py/__init__.py
</code></pre>

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

python linux python-3.x cross-platform travis-ci