Recent

Author Topic: Unable to `RunCommand('/bin/ps',['-eo','pmem,rss,pid,command'], psOut)` on macos  (Read 628 times)

d-_-b

  • New Member
  • *
  • Posts: 24
Hi,

I believe the following code should just work?

But
Code: Pascal  [Select]
  1. RunCommand('/bin/ps',['-eo','pmem,rss,pid,command'], psOut)
always return
Code: Pascal  [Select]
  1. False
.

Any suggestions?

Code: Pascal  [Select]
  1. program runcmd_ps;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  7.   cthreads,
  8.   {$ENDIF}{$ENDIF}
  9.   Classes, SysUtils, CustApp,
  10.   process
  11.   { you can add units after this };
  12.  
  13. type
  14.  
  15.   { TMyApplication }
  16.  
  17.   TMyApplication = class(TCustomApplication)
  18.   protected
  19.     procedure DoRun; override;
  20.   public
  21.     constructor Create(TheOwner: TComponent); override;
  22.     destructor Destroy; override;
  23.     procedure WriteHelp; virtual;
  24.   end;
  25.  
  26. { TMyApplication }
  27.  
  28. procedure TMyApplication.DoRun;
  29. var
  30.   ErrorMsg, psOut: String;
  31. begin
  32.   // quick check parameters
  33.   ErrorMsg:=CheckOptions('h', 'help');
  34.   if ErrorMsg<>'' then begin
  35.     ShowException(Exception.Create(ErrorMsg));
  36.     Terminate;
  37.     Exit;
  38.   end;
  39.  
  40.   // parse parameters
  41.   if HasOption('h', 'help') then begin
  42.     WriteHelp;
  43.     Terminate;
  44.     Exit;
  45.   end;
  46.  
  47.   // if not RunCommand('/bin/ps',['-eo','pmem,rss,pid,command'], psOut) then begin // thanks Hansaplast
  48.   if RunCommand('/bin/ps',['-eo','pmem,rss,pid,command'], psOut) then begin  
  49.     writeln(psOut)
  50.   end;
  51.  
  52.   // stop program loop
  53.   Terminate;
  54. end;
  55.  
  56. constructor TMyApplication.Create(TheOwner: TComponent);
  57. begin
  58.   inherited Create(TheOwner);
  59.   StopOnException:=True;
  60. end;
  61.  
  62. destructor TMyApplication.Destroy;
  63. begin
  64.   inherited Destroy;
  65. end;
  66.  
  67. procedure TMyApplication.WriteHelp;
  68. begin
  69.   { add your help code here }
  70.   writeln('Usage: ', ExeName, ' -h');
  71. end;
  72.  
  73. var
  74.   Application: TMyApplication;
  75. begin
  76.   Application:=TMyApplication.Create(nil);
  77.   Application.Title:='My Application';
  78.   Application.Run;
  79.   Application.Free;
  80. end.
  81.  
« Last Edit: June 01, 2019, 12:34:07 pm by d-_-b »
Code: Pascal  [Select]
  1. mov     ax,0013h
  2. int     10h
Denthor thanks for the vga programming tutorials | Download all tutorials

d-_-b

  • New Member
  • *
  • Posts: 24
Mmm, I seem to be corrected, because I broke the above problem to a test program and it seems to work with a basic TCustomApplication code path.

But in my more advance fptuitreemap.pas codebase it still fails my 'test ps list for macos...' test??!
Code: Pascal  [Select]
  1. mov     ax,0013h
  2. int     10h
Denthor thanks for the vga programming tutorials | Download all tutorials

Hansaplast

  • Hero Member
  • *****
  • Posts: 538
  • Tweaking4All.com
    • Tweaking4All
I think you have to remove the "not" in line 47?
Maybe you overlooked that one ...?


I just did a little test and this works correctly;


Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3.  
  4. {$mode objfpc}{$H+}
  5.  
  6.  
  7. interface
  8.  
  9.  
  10. uses
  11.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, process;
  12.  
  13.  
  14. type
  15.  
  16.  
  17.   { TForm1 }
  18.  
  19.  
  20.   TForm1 = class(TForm)
  21.     Button1: TButton;
  22.     Memo1: TMemo;
  23.     procedure Button1Click(Sender: TObject);
  24.   private
  25.  
  26.  
  27.   public
  28.  
  29.  
  30.   end;
  31.  
  32.  
  33. var
  34.   Form1: TForm1;
  35.  
  36.  
  37. implementation
  38.  
  39.  
  40. {$R *.lfm}
  41.  
  42.  
  43. { TForm1 }
  44.  
  45.  
  46. procedure TForm1.Button1Click(Sender: TObject);
  47. var
  48.   s:ansistring;
  49. begin
  50.   if RunCommand('/bin/ps',['-eo','pmem,rss,pid,command'], s) then
  51.     Memo1.Text:=s;
  52. end;
  53.  
  54.  
  55. end.        


RunCommand returns True if the function executed successfully.


I'm running MacOS Mojave 10.14.5, and Lazarus 2.1.0 r61306M FPC 3.0.4 x86_64-darwin-cocoa (alpha) (from trunk).

d-_-b

  • New Member
  • *
  • Posts: 24
I think you have to remove the "not" in line 47?

Thanks yes that was the issue in my example *doh*. But please see my more advance issue.

I'm going to add more of my tui code to the test case until runcommand start to fail for me again or I end up with a working example.

Thanks for having a look,
« Last Edit: June 01, 2019, 12:33:15 pm by d-_-b »
Code: Pascal  [Select]
  1. mov     ax,0013h
  2. int     10h
Denthor thanks for the vga programming tutorials | Download all tutorials

Hansaplast

  • Hero Member
  • *****
  • Posts: 538
  • Tweaking4All.com
    • Tweaking4All
Happens to the best of us and happy to help when I can  ;)  ...


As for your more advanced code,... not sure what to tell you there.
It all looks OK.


I even tested it with


Code: Pascal  [Select]
  1.   if not RunCommand('/bin/ps',['-eo','pmem,rss,pid,command'], s) then
  2.     Memo1.Text:='FAIL'
  3.   else
  4.     Memo1.Text:=s;


and (invalid command)


Code: Pascal  [Select]
  1.   if not RunCommand('/bin/psbad',['-eo','pmem,rss,pid,command'], s) then
  2.     Memo1.Text:='FAIL'
  3.   else
  4.     Memo1.Text:=s;


and (invalid parameters)


Code: Pascal  [Select]
  1.   if not RunCommand('/bin/ps',['-eoasldjaghsikafgladgfakls','pmem,rss,pid,command'], s) then
  2.     Memo1.Text:='FAIL'
  3.   else
  4.     Memo1.Text:=s;


and they all work as expected, but then again, I'm not very familiar with TCustomApplication.

d-_-b

  • New Member
  • *
  • Posts: 24
Eureka! While the drawing might be broken in the gitlab-runner output it means RunCommand could execute!

But I don't know were the problem was except between keyboard and chair. I actually think my understanding of {IFDEF} blocks for OS detection might have been wrong.

Code: Pascal  [Select]
  1.     {$IFDEF UNIX}
  2.     {$IFDEF DARWIN} // mac - powerpc & intel based
  3.       psArg0 := '-eo';
  4.       psArg1 := 'pmem,rss,pid,command';
  5.     {ELSE} // same as IFDEF LINUX?
  6.       psArg0 := '-eo';
  7.       psArg1 := 'pmem,rss,pid,cmd';
  8.     {$ENDIF}
  9.  

That "same as IFDEF LINUX?" seems not to be true so I passed `psArg1 := 'pmem,rss,pid,cmd';` to `ps` and then RunCommand failed because `ps` on macos wants `command` not `cmd`. This is speculation.

Because as mentioned after reworking my code it works.

Hansaplast thanks for your input!
Code: Pascal  [Select]
  1. mov     ax,0013h
  2. int     10h
Denthor thanks for the vga programming tutorials | Download all tutorials

Hansaplast

  • Hero Member
  • *****
  • Posts: 538
  • Tweaking4All.com
    • Tweaking4All
Cool!  ;)
Ehm just wondering if this shouldn't look more like so:


Code: Pascal  [Select]
  1.   {$IFDEF UNIX}
  2.       {$IFDEF DARWIN} // mac - powerpc & intel based
  3.           psArg0 := '-eo';
  4.           psArg1 := 'pmem,rss,pid,command';
  5.       {$ELSE} // same as IFDEF LINUX?
  6.           psArg0 := '-eo';
  7.           psArg1 := 'pmem,rss,pid,cmd';
  8.       {$ENDIF}
  9.   {$ENDIF}


I tried to find a wiki link, but somehow this page turns up blank? Google Cache still has it here.