从php代码内部执行shell脚本


Executing shell script from inside php code

我想做的是使用php执行youtube-dl -x --audio-format mp3 "token",并获得以下参数的json:

  • 状态(错误=0/成功=1)
  • 保存的文件url(您将在控制台结果示例中看到它:[avconv] Destination: Jennifer Lopez - Booty ft. Iggy Azalea-nxtIRArhVD4.mp3

这是我写的PHP代码。

<?php
if ($_GET["token"]) {
            $url =  $_GET["token"];
            $template = '/home/website/public_html/%(id)s.%(ext)s';
            $string = ('youtube-dl -x --audio-format mp3 ' . escapeshellarg($url) . ' ' . escapeshellarg($template));
            $descriptorspec = array(
                0 => array("pipe", "r"),  // stdin
                1 => array("pipe", "w"),  // stdout
                2 => array("pipe", "w"),  // stderr
            );
            $process = proc_open($string, $descriptorspec, $pipes);
            $stdout = stream_get_contents($pipes[1]);
            fclose($pipes[1]);
            $stderr = stream_get_contents($pipes[2]);
            fclose($pipes[2]);
            $ret = proc_close($process);
            echo json_encode(array('status' => $ret, 'errors' => $stderr,
                'url_orginal' => $url, 'output' => $stdout,
                'command' => $string));
        }
?>

基本上它执行

youtube-dl -x --audio-format mp3 "token"

当我在控制台中(通过SSH)执行相同的命令时,我会得到类似的结果

[youtube] Setting language
[youtube] Confirming age
[youtube] nxtIRArhVD4: Downloading webpage
[youtube] nxtIRArhVD4: Downloading video info webpage
[youtube] nxtIRArhVD4: Extracting video information
[youtube] nxtIRArhVD4: Encrypted signatures detected.
[youtube] nxtIRArhVD4: Downloading js player vflE7vgXe
[download] Destination: Jennifer Lopez - Booty ft. Iggy Azalea-nxtIRArhVD4.m4a
[download] 100% of 3.93MiB in 00:00
[avconv] Destination: Jennifer Lopez - Booty ft. Iggy Azalea-nxtIRArhVD4.mp3
Deleting original file Jennifer Lopez - Booty ft. Iggy Azalea-nxtIRArhVD4.m4a (pass -k to keep)

当我在php环境中执行相同的命令时,得到以下json结果

    {
   "status":1,
   "errors":"WARNING: The url doesn't specify the protocol, trying with http'nWARNING: Could not send HEAD request to http:'/'/'/home'/website'/public_html'/%(id)s.%(ext)s: 'nWARNING: Falling back on generic information extractor.'nERROR: Unable to download webpage: 'n",
   "url_orginal":"nxtIRArhVD4",
   "output":"[youtube] Setting language'n[youtube] Confirming age'n[youtube] nxtIRArhVD4: Downloading webpage'n[youtube] nxtIRArhVD4: Downloading video info webpage'n[youtube] nxtIRArhVD4: Extracting video information'n[youtube] nxtIRArhVD4: Encrypted signatures detected.'n[youtube] nxtIRArhVD4: Downloading js player vflE7vgXe'n[download] Destination: Jennifer Lopez - Booty ft. Iggy Azalea-nxtIRArhVD4.m4a'n'r[download] 0.0% of 3.93MiB at 729.44KiB'/s ETA 00:05'r[download] 0.1% of 3.93MiB at 1.86MiB'/s ETA 00:02'r[download] 0.2% of 3.93MiB at 3.86MiB'/s ETA 00:01'r[download] 0.4% of 3.93MiB at 7.69MiB'/s ETA 00:00'r[download] 0.8% of 3.93MiB at 13.79MiB'/s ETA 00:00'r[download] 1.6% of 3.93MiB at 17.80MiB'/s ETA 00:00'r[download] 3.2% of 3.93MiB at 17.64MiB'/s ETA 00:00'r[download] 6.3% of 3.93MiB at 17.79MiB'/s ETA 00:00'r[download] 12.7% of 3.93MiB at 20.88MiB'/s ETA 00:00'r[download] 25.4% of 3.93MiB at 25.21MiB'/s ETA 00:00'r[download] 50.8% of 3.93MiB at 28.47MiB'/s ETA 00:00'r[download] 100.0% of 3.93MiB at 41.23MiB'/s ETA 00:00'r[download] 100% of 3.93MiB in 00:00'n[avconv] Destination: Jennifer Lopez - Booty ft. Iggy Azalea-nxtIRArhVD4.mp3'nDeleting original file Jennifer Lopez - Booty ft. Iggy Azalea-nxtIRArhVD4.m4a (pass -k to keep)'n[generic] %(id)s: Requesting header'n[generic] %(id)s: Downloading webpage'n",
   "command":"youtube-dl --extract-audio --audio-format mp3 'nxtIRArhVD4' ''/home'/website'/public_html'/%(id)s.%(ext)s'"
}

事实上php做工作并保存文件,但输出不一样,我无法获得目标文件的url。

我做错了什么?有什么建议吗?

您的命令$string似乎没有正确生成。您的$url参数可能为空。

如果你看到错误,它正在尝试加载网页http:///home/website/public_html/%(id)s.%(ext)s

我猜$url一定是空的,这导致第四个参数(你的输出文件)变成了第三个参数(视频URL),所以它试图将其加载为URL,因此出现了错误。

尝试在启动$url之后查看它的内容,看看它的值是什么,确保它实际上是一个URL。如果它是正确的,那么检查$string的内容,确保命令实际上是完整的,甚至尝试手动运行该命令,看看会发生什么,escapeshellarg()可能会导致比它想要解决的更多的问题;我建议您对输入进行一些不同的验证,例如YouTube URL的preg_match()