* * *

Author Topic: How to get the output of a bash script  (Read 2440 times)

JohnSmith

  • New member
  • *
  • Posts: 20
How to get the output of a bash script
« on: September 25, 2017, 12:55:18 am »
Hi

I would like to get the output into Lazarus

cat <(grep 'cpu ' /proc/stat) <(sleep 1 && grep 'cpu ' /proc/stat) | awk -v RS="" '{print ($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)}'

Thanks

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 706
Re: How to get the output of a bash script
« Reply #1 on: September 25, 2017, 06:29:50 am »
hello,
you can put your command  in a shell script cpulaz.sh (dont forget execute permission on it) :
Code: [Select]
#!/bin/bash
cat <(grep 'cpu ' /proc/stat) <(sleep 1 && grep 'cpu ' /proc/stat) | awk -v RS="" '{print ($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)}'
and call it in lazarus like that :
Code: Pascal  [Select]
  1. implementation
  2. uses process;
  3. {$R *.lfm}
  4. { TForm1 }
  5. procedure TForm1.Button8Click(Sender: TObject);
  6.  var  hprocess: TProcess;
  7.    OutputLines: TStringList;
  8.    OutputError: TstringList;
  9.   begin
  10.   OutputLines:=TStringList.Create;
  11.   OutputError:=TStringList.Create;
  12.   hProcess := TProcess.Create(nil);
  13.   hProcess.Executable := '/bin/bash';
  14.   hprocess.Parameters.Add('cpulaz.sh');
  15.   hProcess.Options := hProcess.Options + [poWaitOnExit, poUsePipes];
  16.   hProcess.Execute;
  17.   OutputLines.LoadFromStream(hprocess.Output);
  18.   OutputError.Add('Error :');
  19.   OutputError.LoadFromStream(hProcess.Stderr);
  20.   if OutputError.Text <> '' then showMessage(OutputError.Text)
  21.   else     ShowMessage(OutputLines.Text);
  22.   hProcess.Free;
  23.   OutputLines.Free;
  24.   Outputerror.Free;
  25. end;

Friendly, J.P

JohnSmith

  • New member
  • *
  • Posts: 20
Re: How to get the output of a bash script
« Reply #2 on: September 25, 2017, 01:14:16 pm »
Thank you, appreciate !!

Kays

  • Full Member
  • ***
  • Posts: 112
  • Whasup!?
    • KaiBurghardt.de
Re: How to get the output of a bash script
« Reply #3 on: October 14, 2017, 11:59:53 pm »
I hate such “design”, though. I think its more readable, if you just stay in Pascal,
 however as usual you have to deal with other issues (EDivByZero/RTE200 to name one):
Code: Pascal  [Select]
  1. program pcr(input, output, stderr);
  2.  
  3. uses
  4.         // for fpSleep()
  5.         baseUnix;
  6.  
  7. const
  8.         kStatPath = '/proc/stat';
  9.  
  10. type
  11.         // according to /usr/share/doc/linux-doc/filesystems/proc.txt.gz
  12.         cpuStat = record
  13.                         user: longword;
  14.                         nice: longword;
  15.                         system: longword;
  16.                         idle: longword;
  17.                         iowait: longword;
  18.                         irq: longword;
  19.                         softirq: longword;
  20.                         steal: longword;
  21.                         guest: longword;
  22.                         guest_nice: longword;
  23.                 end;
  24.  
  25. // reads CPU statistics from /proc/stat
  26. function retrieveTotalCpuStat(): cpuStat;
  27. var
  28.         beginningOfLine: string[4];
  29.         stat: text;
  30. begin
  31.         assign(stat, kStatPath);
  32.         {$iochecks off}
  33.         reset(stat);
  34.         {$iochecks on}
  35.        
  36.         if IOResult() = 0 then
  37.         begin
  38.                 while not eof(stat) do
  39.                 begin
  40.                         read(stat, beginningOfLine);
  41.                         // this function only cares about the total CPU statistics
  42.                         if beginningOfLine = 'cpu ' then
  43.                         begin
  44.                                 // can't directly read(stat, retrieveTotalCpuStat) here
  45.                                 with retrieveTotalCpuStat do
  46.                                 begin
  47.                                         read(stat, user);
  48.                                         read(stat, nice);
  49.                                         read(stat, system);
  50.                                         read(stat, idle);
  51.                                         read(stat, iowait);
  52.                                         read(stat, irq);
  53.                                         read(stat, softirq);
  54.                                         read(stat, steal);
  55.                                         read(stat, guest);
  56.                                         read(stat, guest_nice);
  57.                                 end;
  58.                                 // simpler than adding an additional "finished"-flag
  59.                                 if not seekEof(stat) then
  60.                                 begin
  61.                                         writeLn(stderr, 'error: EOF not found');
  62.                                         close(stat);
  63.                                         halt(1);
  64.                                 end;
  65.                         end
  66.                         else
  67.                         begin
  68.                                 // just advance file pointer
  69.                                 readLn(stat);
  70.                         end;
  71.                 end;
  72.                 close(stat);
  73.         end
  74.         // else IOResult() reported an error
  75.         else
  76.         begin
  77.                 retrieveTotalCpuStat := default(cpuStat);
  78.         end;
  79. end;
  80.  
  81.  
  82. type
  83.         relativeTime = (earlier, later);
  84.  
  85. var
  86.         cpuStats: array[relativeTime] of cpuStat;
  87.         sysUserDelta, sysUserIdleDelta: longword;
  88.  
  89. begin
  90.         // gather data
  91.         cpuStats[earlier] := retrieveTotalCpuStat();
  92.         if fpSleep(1) <> 0 then
  93.         begin
  94.                 writeLn(stderr, 'error: can''t sleep');
  95.                 halt(1);
  96.         end;
  97.         cpuStats[later] := retrieveTotalCpuStat();
  98.        
  99.        
  100.         // calculations
  101.         sysUserDelta := cpuStats[later].user - cpuStats[earlier].user +
  102.                         cpuStats[later].system - cpuStats[earlier].system;
  103.         sysUserIdleDelta := sysUserDelta +
  104.                         cpuStats[later].idle - cpuStats[earlier].idle;
  105.        
  106.         if sysUserIdleDelta = 0 then
  107.         begin
  108.                 writeLn(stderr, 'error: attempted division by zero');
  109.                 halt(2);
  110.         end;
  111.        
  112.         // output
  113.         writeLn((sysUserDelta * 100 / sysUserIdleDelta):24:8);
  114.         exitCode := 0;
  115. end.
« Last Edit: October 15, 2017, 12:01:31 am by Kays »
Yours Sincerely
Kai Burghardt

mai

  • Full Member
  • ***
  • Posts: 133
  • truther
bash script
« Reply #4 on: October 16, 2017, 09:22:24 am »
I don't hate that design at all.

if Pascal was any more helpful - which it isn't - than standard UNIX tools, you might have a point.

but given that Laz & fpp crash on every third click, the topmost solution comes across as a pretty stable idea.  O:-)

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 6243
Re: bash script
« Reply #5 on: October 16, 2017, 11:50:16 am »
I don't hate that design at all.

if Pascal was any more helpful - which it isn't - than standard UNIX tools, you might have a point.

but given that Laz & fpp crash on every third click, the topmost solution comes across as a pretty stable idea.  O:-)

If you don't have anything ontopic to say, maybe it is best to not comment at all.

Thaddy

  • Hero Member
  • *****
  • Posts: 6143
Re: How to get the output of a bash script
« Reply #6 on: October 16, 2017, 12:32:59 pm »
And standard UNIX tools can be perfectly written in Object Pascal.... What's your problem?
I might not give the answer that you want me to.. Peter Green 1969

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 6243
Re: How to get the output of a bash script
« Reply #7 on: October 16, 2017, 12:47:45 pm »
Btw, the easiest is to just run the script interpreter with -c:

Note that this script is sensitive to what shell is used, which flabbergasted me for a short while. (/bin/sh didn't work) That's why I wasn't first post :)

Code: Pascal  [Select]
  1. {$mode delphi}
  2.  
  3. uses process;
  4. var sin,sout : string;
  5. begin
  6.   sin:='cat <(grep ''cpu '' /proc/stat) <(sleep 1 && grep ''cpu '' /proc/stat) | awk -v RS="" ''{print ($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)}''';
  7.   runcommand('/bin/bash',['-c',sin],sout);
  8. // writeln(sin);  // only used to check quoting of input
  9. writeln(sout);
  10. end.
  11.  

Note that all ' are doubled in the input string. This is normal way in Pascal literals to make a ', kind of like \ escape in C.

At the end there is a doubled ' + another ' from closing the pascal literal.

The example is basically the same as Jurassic Pork's, just using some predefined helper routines, and using direct commandline scripts (-c) instead of writing it out to file.

If you just want to run, and not get the output, you can also use fpsystem()
« Last Edit: October 16, 2017, 12:50:01 pm by marcov »

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus