python - 子进程.Popen : 'OSError: [Errno 2] No such file or directory' only on Linux

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

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.

当我的代码(如下所示)在 Windows(我的笔记本电脑和 AppVeyor CI)上执行时,它会执行它应该执行的操作。但是在 Linux(TravisCI 上的 VM)上,它会抛出一个找不到文件的错误。

我在 /home/travis/build/sayak-brm/espeak4py/ 中执行。

ls -l 输出:

$ 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

这表明文件位于它们应该位于的位置。

espeak 文件是一个 Linux ELF 二进制文件。


错误:

$ 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'

代码:

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__)))

测试.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.')

我不明白为什么它只能在一个平台上运行,而不能在另一个平台上运行。

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

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

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

最佳答案

我已经在 Linux 上测试了您的 espeak Python 包装器,它适用于我。 可能这只是 Windows 尾随 \r 字符的问题。 您可以尝试以下操作:

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

要输入 ^M,请键入 Ctrl-V,然后键入 Ctrl-M,然后查看是否运行 sed 命令解决了这个问题。

关于python - 子进程.Popen : 'OSError: [Errno 2] No such file or directory' only on Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39785140/

相关文章:

linux - Bash 脚本 : permanent pipe

multithreading - 如果任何线程有异常,则导致 python 退出

python - pandas groupby 多级标题

python - py2neo.WriteBatch 如何工作?

python - django.db.utils.ProgrammingError : relation "blogango_blog" does not exist

python - 写入现有工作簿

python - 在类级别跟踪 Python 2.7.x 对象属性以快速构造 numpy 数组

regex - 使用正则表达式或在 cat

c++ - 对静态库中类变量的 undefined reference

python - 在 webhook 中解析 JSON