Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.7k views
in Technique[技术] by (71.8m points)

python - 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
')
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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...