Delphi:捕获OSX控制台输出 [英] Delphi: Capture OSX console output

查看:52
本文介绍了Delphi:捕获OSX控制台输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在OSX上,发现下面的Delphi(Firemonkey)代码将控制台输出写入备忘录。当我使用 ls之类的常规命令时,此方法可以正常工作,但不能捕获外部终端应用程序的输出。

I am on OSX and I found the following Delphi (Firemonkey) code to write the console output to a Memo. This works fine when I am using normal commands like "ls", but it doesn't capture the output from external terminal apps.

例如,如果我运行命令行应用程序 youtube-dl,输出仅显示在PAServer日志中,而不显示在备忘录中。

For example, if I run the command line application "youtube-dl", the output shows up only in the PAServer log, but not in the Memo.

有没有办法做到这一点?还是有人可以修改代码以使其正常工作?

Is there a way to do this? Or can someone modify the code to make this work?

const
  libc = '/usr/lib/libc.dylib';

type
  PIOFile = Pointer;

//Create a new stream connected to a pipe running the given command.
function popen(const Command: PAnsiChar; Modes: PAnsiChar): PIOFile; cdecl;
  external libc name '_popen';

//Close a stream opened by popen and return the status of its child.
function pclose(Stream: PIOFile): Integer; cdecl; external libc name '_pclose';

//Return the EOF indicator for STREAM.
function feof(Stream: PIOFile): Integer; cdecl; external libc name '_feof';

//Read chunks of generic data from STREAM.
function fread(Ptr: Pointer; Size: LongWord; N: LongWord;
  Stream: PIOFile): LongWord; cdecl; external libc name '_fread';

//Wait for a child to die.  When one does, put its status in *STAT_LOC
//and return its process ID.  For errors, return (pid_t) -1.
function wait(__stat_loc: PInteger): Integer; cdecl;
  external libc name '_wait';

procedure TForm1.ExecCmdine(const CmdLine: string);
var
  Output: PIOFile;
  Buffer: PAnsiChar;
  TempString: Ansistring;
  Line: AnsiString;
  BytesRead: Integer;
const
  BufferSize: Integer = 1000;
begin
  TempString := '';
  Output := popen(PAnsiChar(Ansistring(CmdLine)), 'r');
  GetMem(Buffer, BufferSize);
  if Assigned(Output) then
  try
    while feof(Output) = 0 do
    begin
      BytesRead := fread(Buffer, 1, BufferSize, Output);
      SetLength(TempString, Length(TempString) + BytesRead);
      Move(Buffer^, TempString[length(TempString) - (BytesRead - 1)], BytesRead);

      while Pos(#10, TempString) > 0 do
      begin
        Line := Copy(TempString, 1, Pos(#10, TempString) - 1);
          Memo1.Lines.Add(UTF8ToString(Line));

        TempString := Copy(TempString, Pos(#10, TempString) + 1, Length(TempString));
      end;
    end;
  finally
    pclose(output);
    wait(nil);
    FreeMem(Buffer, BufferSize);
  end;
end;


推荐答案

罗伯·肯尼迪(Rob Kennedy)有正确的答案,可惜他没有

Rob Kennedy had the correct answer, but sadly he didn't post it as answer, so I will do it.

问题是youtube-dl的控制台输出被打印到stderr而不是stdout,所以我不得不在运行时将2>& 1添加到控制台命令。

The problem was that the console output of youtube-dl gets printed to stderr and not stdout, so I had to add 2>&1 to the console command when running it.

这篇关于Delphi:捕获OSX控制台输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆