sbrm1 sbrm1 - 2 months ago 16
Linux Question

subprocess.Popen: 'OSError: [Errno 13] Permission denied' only on Linux


Code and logs have changed a lot (due to a major rewrite) since the question was asked.


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 permission denied error.




Error:

$ sudo 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 35, in say
self.prevproc = subprocess.Popen(cmd, executable=self.executable, cwd=os.path.dirname(os.path.abspath(__file__)))
File "/usr/lib/python3.2/subprocess.py", line 745, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.2/subprocess.py", line 1361, in _execute_child
raise child_exception_type(errno_num, err_msg)
OSError: [Errno 13] Permission denied
The command "sudo python3 test.py" exited with 1.





Code:

espeak4py/init.py:

#! python3
import subprocess
import os
import platform

class Speaker:
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 generateCmd(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.generateCmd(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




I got the outputs of
ls -l
as @zvone recommended:

$ 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
-rw-rw-r-- 1 travis travis 276306 Sep 29 20:14 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

Answer

This is pretty much off topic on SO, but here's your problem...

This is the executable you are trying to run:

-rw-rw-r-- 1 travis travis 276306 Sep 29 20:14 espeak

Its permissions are rw- read+write for owner (travis), rw- read+write for group (travis), and r-- read for others. There is no permission to execute for anyone.

You have to give x (execute) permission to the user under which the script is running. Or give it to everyone:

chmod 775 espeak

After that, ls- l should say:

-rwxrwxr-x 1 travis travis 276306 Sep 29 20:14 espeak
Comments