jjzjj

php - macOS Sierra 中的更改阻止 "say"在 PHP 脚本中执行

coder 2024-04-21 原文

我有一个带有小站点的 macOS 服务器,该站点使用 say 命令将文本片段转换为音频。

升级到 Sierra 后,一切都很顺利,除了一件事:say 命令在我的 PHP 脚本中包含在 exec() 中时不再起作用。

页面刚刚超时。也没有发现错误。

<?php
    try {
        exec('/usr/bin/say "hello"');
    }
    catch (Exception $e) { echo $e->getMessage(); }
?>

通常我会使用 say -o filename 保存音频片段,但我尝试了所有变体以及其他运行良好的 shell 命令,包括在我的输出文件夹中创建文件。

有趣的是,如果我从命令行运行它,它会起作用——要么大声说出来,要么创建一个输出文件。

macOS Sierra 有 PHP 5.6.24,所以我认为 safe_mode 不适用,对吗?

我想强调的是,PHP 或 say 命令的变化是最近才发生的,与新的操作系统有关。是的,我确实调查并尝试了不同的输出和 stderr 重定向,但脚本只是挂起。

在 Activity Viewer 中看到 say 命令(top 等效的 GUI),我尝试对其进行采样,但不确定是否有帮助:

2695 Thread_1742595   DispatchQueue_1: com.apple.main-thread  (serial)
+ 2695 start  (in libdyld.dylib) + 1  [0x7fffb0f58255]
+   2695 ???  (in say)  load address 0x10907d000 + 0x1fac  [0x10907efac]
+     2695 NewSpeechChannel  (in SpeechSynthesis) + 52  [0x7fff9acd3f19]
+       2695 SpeechChannelHandle::SpeechChannelHandle()  (in SpeechSynthesis) + 265  [0x7fff9acd797f]
+         2695 dispatch_once_f  (in libdispatch.dylib) + 38  [0x7fffb0f220e5]
+           2695 _dispatch_client_callout  (in libdispatch.dylib) + 8  [0x7fffb0f22128]
+             2695 ___ZN13SpeechGlobals8InstanceEv_block_invoke  (in SpeechSynthesis) + 28  [0x7fff9acd54da]
+               2695 SpeechGlobals::SpeechGlobals()  (in SpeechSynthesis) + 471  [0x7fff9acd56db]
+                 2695 xpc_connection_send_message_with_reply_sync  (in libxpc.dylib) + 154  [0x7fffb11b65a8]
+                   2695 dispatch_mach_send_with_result_and_wait_for_reply  (in libdispatch.dylib) + 45  [0x7fffb0f3cf39]
+                     2695 _dispatch_mach_send_and_wait_for_reply  (in libdispatch.dylib) + 591  [0x7fffb0f3cad4]
+                       2695 mach_msg  (in libsystem_kernel.dylib) + 55  [0x7fffb107e867]
+                         2695 mach_msg_trap  (in libsystem_kernel.dylib) + 10  [0x7fffb107f41a]
2695 Thread_1742600
  2695 start_wqthread  (in libsystem_pthread.dylib) + 13  [0x7fffb116f211]
    2695 _pthread_wqthread  (in libsystem_pthread.dylib) + 1426  [0x7fffb116f7b5]
      2695 __workq_kernreturn  (in libsystem_kernel.dylib) + 10  [0x7fffb10874e6]

这些是统计数据:

从打开的文件和端口中,我可以看到我将 stdoutstderr 都设置为 /private/var/log/apache2/error_log 但那里什么也没有显示。

此外,尝试通过更精细的运行来捕获输出,但没有任何乐趣,只是超时(脚本文件夹也是可写的):

<?php   
    try {
        $pipes = array();
        proc_close(proc_open("say hi", array(0 => array("pipe", "r"), 1 => array("pipe", "r"), 2 => array("pipe", "r")), $pipes, dirname(__FILE__), null));
    } catch (Exception $e) { error_log($e->getMessage()); }
?>

更新:High Sierra 是一样的。

最终更新:安装 Mojave 后,删除了大部分 Server.app 功能,我添加了 MAMP 来处理此任务。 如果你愿意,你可以自己听 - 它在 macspeaks.com .

故事继续:在安装 Catalina 期间不知何故,还是 MAMP 更新? (现在5.5),我又把它杀了。唉……

最佳答案

我也遇到过同样的问题。

这是我刚刚想出的一个解决方法,但老实说,我认为仅仅能够从基于 apache 的 php 脚本播放音频是一个大问题。我对为什么会发生这种情况有一些想法,但经过多次测试,我似乎覆盖了我自己的理论。我认为这可能与没有事件的 TTY 有关。我无法通过使用 sudo -i 启动 shell 来播放音频,以及来自 php 的许多其他尝试,但我能够使用本地终端的所有相同命令播放音频,事实证明,也是通过 SSH 进入计算机,这导致了我最新的解决方法.再一次,我认为这是矫枉过正,但到目前为止,这是我能够在基于 web 的 php 驱动脚本(主要是地理围栏相关)中恢复音频的唯一方法。

那么,我们开始吧,是的,我理解其中涉及的风险和愚蠢:

在我的 php 脚本中,我使用类似于此的命令在/tmp 目录中生成一个音频文件:

exec "sudo -u <username> /usr/bin/say -o /tmp/outputfile.aiff --voice=Ava \"<What to Say>\"";

然后在生成音频文件后,我发现从 apache/php 播放它(并实际听到输出)的唯一方法是使用 expect 脚本在本地 ssh 并播放它。所以我的下一行是:

exec "sudo -u <username> -i ~<username>/expectscript";

我的期望脚本如下:

#!/usr/bin/expect -f

spawn /usr/bin/ssh localhost
expect "Password"
send "<PASSWORD>\r"
expect "<username>"
send "/usr/bin/afplay /tmp/outputfile.aiff\r"
expect "<username>"
send "/usr/bin/touch /tmp/touchthis\r"
expect "<username>"
send "exit\r"

确保替换所有 <username>上面是你的用户名(显然没有<>)和<PASSWORD>用你的密码。如果您的 bash 提示不包含您的用户名,您可能需要调整 expect 脚本,因为这是我在 expect 脚本中用来查找返回提示的内容。触摸只是为了确定预期脚本是否有效,并且您可以引用上次触摸文件的时间。

我希望这能引发关于究竟是什么导致了这种情况的讨论,我们可以确定一个更合理的解决方案。我陷入了很多困境,试图找到让它工作的不同方法,我创建了 Automator 应用程序并从 PHP 调用了这些应用程序(没有用。)我以我的用户身份在 shell 中启动 shell,所有命令的执行总是成功完成,只是没有音频输出。我尝试过的所有解决方案都可以在终端上正常工作(甚至可以在终端上运行 php),只是 Apache/PHP 不行。

关于php - macOS Sierra 中的更改阻止 "say"在 PHP 脚本中执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40233677/

有关php - macOS Sierra 中的更改阻止 "say"在 PHP 脚本中执行的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  5. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  6. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  7. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  8. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  9. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  10. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

随机推荐