一部分的内容需要涉及linux的操作,我本是比较喜欢使用 system($cmd[,$res]) 函数来操作linux系统命令。

因为它能够像写shell脚本一样,通过$res来判断上一步是否操作成功。

(PHP操作linux命令前提是已经关闭了safe_mode,或者是将disabled_method中的相关函数释放出来)

一、需求

昨天在做一个测试的时候,需要将以已经存在的文件进行重命名(结合时间戳),然后创建新的文件,然后在进行一步其他的操作,最终会生成一个新的文件

上面的需求中第二部其他操作存在操作的失败性质,如果第二部操作失败了,则需要回滚操作,将之前重命名的结果返回来。

上面的操作是在linux进行的定时任务,关于定时任务结合php在结合linux我会再写一篇文章

二、代码

其实这部分的代码是很简单的,摘出来放在下面,主要流程是:

  • 从数据库中获取一个数组信息
  • 遍历数组执行一系列操作:

    • 将文件名进行重命名
    • 通过操作生成新的文件(这一步存在失败的可能
    • 如果操作失败,回滚第一步操作,恢复原来的文件。
    for($i=0;$i<$countAllRoom;$i++){
            // 从配置中获得ffmpeg截图存放位置
            $photoPos=Config::get('ffmpeg.photoPos');
            // 获得时间戳文件名
            $fileStamp=$allRoomIGuid[$i]['guid']."_".time();
            // 重命名原来的文件 结合timestamp
            $cmd=" mv ".$photoPos."/".$allRoomIGuid[$i]['guid'].".png ".$photoPos."/".$fileStamp.".png";
            // echo($cmd);
            $result=system($cmd,$res);
            echo $res."-";
            // 从配置中获取视频流
            $rtmpUrl=Config::get('view_replace_str.__RTMP_URL__');
            /**
             *  拼接ffmpeg命令行 
             *  - 下面命令表示从 rtmp://192.168.124.129/myapp/10000 视频流的2秒后切一个图
             *  - 存放名称路径是下面的代码
             */
            $cmd="ffmpeg -i ".$rtmpUrl."/".$allRoomIGuid[$i]['guid']." -f image2 -ss 1 -vframes 1 -s 400*300 ".$photoPos."/".$allRoomIGuid[$i]['guid'].".png ";
            // 使用system函数执行系统命令
            // echo $cmd;
            $result=system($cmd,$res);
            echo $res."-";
            if($res==1){
                // 如果执行失败 则说明没有生成新的文件,讲原来的mv操作撤销
                $cmd=" mv ".$photoPos."/".$fileStamp.".png ".$photoPos."/".$allRoomIGuid[$i]['guid'].".png";
                system($cmd,$res);
                echo $res."-";
            }
        }

上面的代码是逻辑的一部分,第二部操作是通过ffmpeg从视频流中截取一个截图,存在在/.../live/路径下,文件名都是固定的格式,从数组中获取。

ffmpeg在截取的时候可能会失败,因此需要通过$res进行判断,如果失败了(shell中0代表成功,非0代表失败),则将重命名的内容再恢复。

php1.jpg

三、问题

上面的逻辑没有问题,但是在实际操作的时候,发现一直无法正确实现。

mv 命令都无法实现,不过ls这样的命令是可以实现的。

  • 后面发现是 live文件夹的权限是755,这个文件都是使用root用户创建的。
  • 我安装apache是apache2.4,操作用户是www,所以原因也比较明朗,用户权限不足,无法对文件进行操作。

四、后记

比较粗暴的做法是*直接给live文件夹 777的权限

比较好的做法是给www用户相关的文件操作权限

如果发现返回的结果是127,则是说明www用户没有操作脚本的权限,应该给予www用户bash权限

$ usermod -s /bin/bash www