我想从PHP调用mpg123
(使用exec
)并监视程序运行时生成的诊断输出。
我一直在互联网上搜索,在命令行程序运行时找不到任何方法来查看命令行程序的重定向输出。
相反,输出文件总是在进程结束后写出来,但我需要在它仍然运行时访问输出,因此我的问题。
测试:
mpg123.exe http://148.251.184.14:8192/stream | tee.exe streaming.txt
...运行exe时,文件streaming.txt`始终为空。
[编者注:因此,mpg123
将诊断输出发送到stderr
]。
另外,我测试了这个:
mpg123.exe http://148.251.184.14:8192/stream > streaming.txt
...但仍然没有运气,因为streaming.txt
仍在运行时,文件mpg123
始终为空。
[编者注:当然,出于与上述相同的原因,命令应为:
mpg123.exe http://148.251.184.14:8192/stream 2> streaming.txt
但是在程序终止之前,你仍然没有在文件streaming.txt
中看到任何内容。
结束说明]
有办法做到这一点吗?看起来很难或甚至不可能...... 谢谢你的帮助。
PS:
使用来自https://mpg123.de/download/win64/1.25.10/
的静态二进制文件Tee.exe:https://sourceforge.net/projects/unxutils/files/unxutils/current/
答案 0 :(得分:3)
例如,您可以从GnuWin32获取tail
(它在包coreutils中)。然后:
在一个命令提示符窗口中运行tail -F output-file
。这最初会坐在那里,因为还没有output-file
。让它坐下。
在另一个命令提示符窗口中运行your-command > output.file
。
在第一个命令提示符窗口中,tail
将显示output-file
生成的内容。
注1:程序your-command
可以缓冲其输出,以便以块的形式写入。某些程序可以选择最小化输出缓冲,例如sed -u
或grep --line-buffered
。
注2:tail
尽可能快地工作,但Windows上的控制台输出速度很慢。程序完全可以比tail
更快地生成多输出。
我已使用dir /s C:\ > Ls-lR.txt
和tail Ls-lR.txt
测试了此过程。
querent想要监控的具体程序是MPG123。这个计划:
通常不会写入标准输出,实际上关闭标准输出,除非它想要写WAV数据。
将诊断消息写入标准错误,但仅当标准错误未重定向或时才会显示选项-v
。
因此...
打开命令提示符窗口并键入tail -F mpg123.out
。由于没有名为mpg123.out
的文件,tail
会等待。让它等一下。
C> tail -F MPG123.out
打开第二个命令提示符窗口,然后运行mpg123
将标准错误重定向到mpg123.out
,和
使用选项-v
。
C> mpg123.exe 2>MPG123.out -v "\path\to\the\music\file.mp3"
在第一个窗口中,观察MPG123的诊断消息。
答案 1 :(得分:0)
也许可以使用机器上已有的“T恤”。我没有你的mpg123.exe可执行文件,所以我无法测试它。
powershell -NoProfile -Command "& mpg123.exe [StreamURL] | Tee-Object -FilePath .\streaming.txt"
修改
根据来自@AlexP的信息,mpg123.exe正在写入stderr,我会尝试:
powershell -NoProfile -Command "& mpg123.exe [StreamURL] 2>&1 | Tee-Object -FilePath .\streaming.txt"
答案 2 :(得分:0)
我已经决定删除我的原始答案并发布一个新的答案,因为虽然旧答案事实上是正确的,但它并没有很好地回答这个问题。现在,我了解OP实际上正在做什么,我可以正确回答这个问题。
这个问题实际上非常简单。大多数平台上的大多数程序(尤其是命令行程序)都包含用于检测stdout
或stderr
是否已重定向到文件(> file
)或管道(例如| tee
}的逻辑)。这个逻辑实际上通常埋没在运行时库中,因此程序可以免费获取它,这就是为什么他们几乎全都这样做了,而且我确信mpg123
这是一个相对简单的野兽。我在下面说的几乎适用于任何程序。
现在,这个逻辑的作用是决定是否缓冲输出到stdout
/ stderr
(它可能会为每个输出做出不同的决定)。如果输出直接进入控制台(或者,在Unix中,终端),那么它根本不被缓冲(或者可能只是基于每行)。一旦程序生成,所有内容都会被发送出去。
另一方面,如果输出 重定向,则mpg123
会检测到这种情况并将数据写入块(通常为4k块),如果总量为程序运行时生成的输出小于缓冲区的大小然后在程序终止之前,您不会在输出文件或管道中看到任何内容,此时刷新缓冲区并关闭文件(所以你看到了,正如OP指出的那样。)
现在,了解所有这些,我们可以解释OP在运行mpg123
时观察到的行为。事实上,这不是mpg123
可能对文件句柄做的任何错综复杂的杂耍,而且当你添加-v
时行为的改变只是一个副作用。您看到的是输出重定向时使用的不同缓冲策略的直接结果。
所以,使用OP链接的二进制文件,这个命令:
mpg123 http://148.251.184.14:8192/stream
直接在控制台上生成以下输出(因为没有缓冲):
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3
version 1.25.10; written and copyright by Michael Hipp and others
free software (LGPL) without any warranty but with best wishes
Directory: http://148.251.184.14:8192/
Playing MPEG stream 1 of 1: stream ...
ICY-NAME: Chroma Metal
ICY-URL: http://chromaradio.com
MPEG 1.0 L III cbr128 44100 j-s
ICY-META: StreamTitle='Avantasia - The Seven Angels';
然后继续通过声卡播放流,这需要相当长的时间。以上信息写入stdout
(mpg123
始终将诊断信息写入stdout
)。
但是,此命令的行为有所不同,因为输出是缓冲的(请注意stdout
的重定向):
mpg123 http://148.251.184.14:8192/stream 2>x.txt
如OP所述,这只是在播放流时创建一个零长度文件,因为诊断输出的总量适合mpg123
的内部缓冲区所以它只保留直到程序终止,此时输出正确地在文件中出现,原因如上所述。
最后,此命令添加了-v
参数:
mpg123 -v http://148.251.184.14:8192/stream 2>x.txt
当程序运行时, 在x.txt
生成一些输出,因为缓冲区填满了-v
标志生成的额外诊断信息
mpg123
必须将其写入磁盘。 -v
标志表示verbose
。这就是额外输出的来源。
请注意,虽然当你这样做时,文件中的数据仍然总是落后一些(因为下一个缓冲区已经建立并且在它已满之前不会输出),所以在添加{{1}时可能会得到你想要的东西(或至少其中一些),它没有改变潜在的问题。如果在一个控制台窗口中运行上述命令而在另一个控制台窗口中运行-v
,则可以非常清楚地看到这一点。当你这样做时,前5秒左右没有任何显示。然后出现一些(部分)输出,因此它继续。
所以我希望能够解决问题。 Windows和Unix在这方面的表现几乎相同。我将编辑OP的问题,使其不那么混乱。现在有点不整洁。