macOS Sierra中的更改阻止了“ say”在PHP脚本中执行

Jos*_*abr 5 php exec macos-sierra

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

升级到Sierra后,除了一件事情外,一切都变得顺利了:将say命令包装exec()到我的PHP脚本中后,该命令不再起作用。

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

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

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

有趣的是,如果我从命令行运行它,则可以正常工作-大声说出来或创建一个输出文件。

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

我想强调一下,在新操作系统中,PHP或say命令的更改是最近的。是的,我确实调查过并尝试了不同的输出和stderr重定向,但是脚本只是挂起了。

say在Activity Viewer(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]
Run Code Online (Sandbox Code Playgroud)

这些是统计信息: 活动查看器>统计信息

而从打开的文件和港口,我看得出来,我都设置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()); }
?>
Run Code Online (Sandbox Code Playgroud)

更新:高塞拉山脉是相同的。

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

故事继续:在安装Catalina的过程中,还是MAMP更新了?(现在是5.5版),我再次杀死了它。叹...

小智 0

我也经历过同样的问题。

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

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

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

exec "sudo -u <username> /usr/bin/say -o /tmp/outputfile.aiff --voice=Ava \"<What to Say>\"";
Run Code Online (Sandbox Code Playgroud)

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

exec "sudo -u <username> -i ~<username>/expectscript";
Run Code Online (Sandbox Code Playgroud)

我的期望脚本如下:

#!/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"
Run Code Online (Sandbox Code Playgroud)

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

我希望这能引发对实际原因的讨论,以便我们能够确定更合理的解决方案。我陷入了很多困境,试图找到不同的方法来让它工作,我创建了 Automator 应用程序并从 PHP 调用这些应用程序(不起作用。)我以我的用户身份在 shell 中启动了 shell,所有命令的执行总是成功完成,只是没有音频输出。我尝试过的所有解决方案都可以从终端(甚至从终端的 php)正常工作,只是不能从 Apache/PHP 工作。