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

隐身守侯 提交于 2019-12-20 02:57:04

问题


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

回答1:


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


来源:https://stackoverflow.com/questions/39777345/subprocess-popen-oserror-errno-13-permission-denied-only-on-linux

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