本文介绍了macOS Sierra的更改可防止“说".在PHP脚本中执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a macOS server with a little site which converts text snippets to audio using say command.

通过升级到Sierra,除了一件事情,一切都进行得很顺利:say命令在用我的PHP脚本包裹在exec()中后不再起作用.

With upgrade to Sierra, everything went smooth except one thing: the say command doesn't work any more when wrapped in exec() in my PHP script.

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

The page just times out. No error is caught either.

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

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

Typically I would save the audio snippets with say -o filename but I tried all the variants and also other shell commands which worked fine including creating files in my output folder.

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

Interesting is that if I run it from a command line, it works - either says it loud or creates an output file.

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

macOS Sierra has PHP 5.6.24 so I don't think safe_mode applies, righht?

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

I would like to emphasise that the change in either PHP or say command was quite recent, with the new OS. Yes I did look into and tried different output and stderr redirection but the script just hangs.

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

Seeing the say command in Activity Viewer (GUI for top equivalent), I tried to sample it, not sure if it helps:

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,但那里什么也没有显示.

And from open files and ports, I could see that I set both stdout and stderr to /private/var/log/apache2/error_log yet nothing shows there at all.

此外,尝试捕获运行更复杂的输出,但是没有乐趣,只是超时(脚本文件夹也是可写的):

Also, tried to capture outputs with more elaborate run, but no joy, just timeout (the script folder is also writable):

<?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相同.

UPDATE: High Sierra is the same.

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

FINAL UPDATE: after installing Mojave, which removes most of the Server.app features, I added MAMP to handle this task. Hear it for yourselves if you wish - it's at macspeaks.com.

故事继续:在安装Catalina期间,还是以某种方式更新了MAMP? (现在是5.5版),我再次杀死了它. igh ...

THE STORY CONTINUES: somehow during the install of Catalina, or was it MAMP update? (now on 5.5), I killed it again. Sigh...

推荐答案

在Jenkins作业上使用say命令时,我遇到了同样的问题.我的Jenkins服务器在macOS Sierra上充当守护程序.

I have experienced same problem while using say command on my Jenkins job. My Jenkins server is working as daemon on macOS Sierra.

在我的情况下,我这样解决了这个问题:

In my case I solved this problem like this:

  1. jenkins用户身份登录,并使用ssh-keygen生成ssh密钥.
  2. .ssh/authorized-keys后面附加~/.ssh/id_rsa.pub,这样就不会要求输入密码.

  1. Login as jenkins user and generate ssh key with ssh-keygen.
  2. Append ~/.ssh/id_rsa.pub to .ssh/authorized-keys so that password will not be requested.

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized-keys

  • 更改我的Jenkins作业,该作业使用say命令,如下所示:

  • Change my Jenkins job which use say command like this:

    ssh localhost say -v Alex "Test"
    

  • 对不起,我尚未使用Apache/PHP进行过测试,但是为什么不这样尝试呢?

    I’m sorry, I have not tested with Apache/PHP, but why don't you try this way like this:

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

    这篇关于macOS Sierra的更改可防止“说".在PHP脚本中执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    09-26 20:21