[Solved] Read last line from Process

Post

Posted
Rating:
#1 (In Topic #394)
Avatar
Regular
Philippe734 is in the usergroup ‘Regular’
Hello,
Considering the following concept bash:

Code

command | while read line; do
    if [ "$condition" == "$line"  ]; then
        echo "$line"
        break
    fi
    done
With an example:

Code

x=10
(while :; do echo "$x";   x=$(( $x + 1 )); done) | while read line; do
    if [ "256071" == "$line"  ]; then
        echo "$line"
        break
    fi
    done
I want to convert this in Gambas, with Exec and Process Read, please, can you help me ?

Code (gambas)

  1. hProc = Exec ["command"] For Read As "Contents"

Code (gambas)

  1. Public Sub Contents_Read()  
  2.   Dim sLine As String
  3.  
  4.     ' How to read the last line of the standard process output ?
  5.    ...
  6.     'sOutput &= sLine
  7.   Until sOutput = "text"
  8.   ' To kill or close the process : Contents_Kill or hProc.Kill or hProc.Close ?
  9.  

In Contents-Read () how to read the last line of the standard output of the process ?
What code use to close or kill the process ?

 Linux & Android enthusiast - France
Online now: No Back to the top

Post

Posted
Rating:
#2
Avatar
Guru
cogier is in the usergroup ‘Guru’
Run this code in a new 'Graphical' application. Hopefully it will help you.

Code (gambas)

  1. hProcess As Process
  2. TextArea1 As TextArea
  3.  
  4. Public Sub Form_Open()
  5.  
  6.   BuildForm
  7.   Go
  8.  
  9.  
  10. Public Sub Go()
  11.  
  12.   hProcess = Shell "tree" For Read As "Process"
  13.  
  14.  
  15. Public Sub Process_Read()
  16.  
  17.   Dim sLine As String
  18.  
  19.   Read #Last, sLine, -256
  20.   TextArea1.Text &= sLine
  21.  
  22.  
  23. Public Sub BuildForm()
  24.  
  25.   With Me
  26.     .Arrangement = Arrange.Vertical
  27.     .Height = 500
  28.     .Width = 300
  29.     .Padding = 5
  30.  
  31.   With TextArea1 = New TextArea(Me) As "TextArea1"
  32.     .Expand = True
  33.  
Online now: No Back to the top

Post

Posted
Rating:
#3
Avatar
Regular
Philippe734 is in the usergroup ‘Regular’
I known already it, I know read the help of Gambas  ;)

Code (gambas)

  1. Read #Last, sLine, -256
It's not the answer I need. Currently, this line return the whole output. Considering a bash command which run in an infinite loop. I want only the last line of the standard output, test it with my condition and let the run until my condition is true, then kill the process.
Edit : for more detail my need, I edit my first post with a concrete bash command.

 Linux & Android enthusiast - France
Online now: No Back to the top

Post

Posted
Rating:
#4
Avatar
Regular
Serban is in the usergroup ‘Regular’
Maybe I got it wrong…
In my view, what you need is to perform a dynamycal analyisis on the output of the console.
That is more difficult, since you need to know precisely if the output is something formatted as lines. Otherwise, you end up with an endless string which has only one line, which is always "the last line". So we're in a vicious cricle here: <COLOR color="#FF0000">what is "last line"?</COLOR>
If I understood it right, the first step would to direct the output from the console, into a string variable.
As an intermediate phase, you load it into a TextArea and get the image on how it looks like:
All you need here is a FMain module and a TextArea1 control.
To trigger the process, put a Button1 above the TextArea1, then on Button1_Click() event, call the procedure that does the Shell or Exec. Say…


Code (gambas)

  1. '---
  2. Public Sub GetConsoleOutput()
  3. '--- Code for spying the console.
  4. '---
  5. Public Sub Button1_Click()
  6.   GetConsoleOutput()
  7. '--- This goes into FMain.Class:
  8. Dim strConsoleOutput, strToken, strCurrentLine As String
  9. '...
  10. TextArea1.Wrap=False
  11. TextArea1.Text=strConsoleOutput
  12. '--- Now, how does it look like? Do we have lines?
  13. '--- IF so, then we cycle through the lines, using a Stream, then a clause.
  14. '... stream Dim ,open etc.
  15. While Not hndStream.EOF
  16.   If InStr(strToken ,strCurrentLine) Then   '--- We found what we're looking for. Do the job we need.
  17.     DoTheJobINeed()
  18.   Else    '--- We might need to do something here. Either ignore the line since we are missing what we are looking for, OR whatever else.
  19.     DoTheAlternateJob()
  20.   End If
  21.  
  22.  
If you do this, you need to set the Wrap property to "False ", to prevent wrapping the contents. This is how you find out if there is only one string, or there are more lines.
In the code above, I admitted <COLOR color="#FF0000">by default</COLOR> that we got LINES. That is, more than one line, which is always "LastLine".
<COLOR color="#FF0000">NOTE:</COLOR>
I wrote the code in place from memory so YOU GOT TO TEST IT, and obviously, fill the required lines to catch the console output into the string [strConsoleOutput].
Since I hate console, I leave it up to you to write the appropriate code.

The other way around…
I have to figure out how to do this, because it goes beyond my understanding how you can test a string that is continuously generated and you want to find something in it, in real time. Meaning, as it is generated.

The other thing you need to do, is write the code for the Stream: to open it, read the lines from [strConsoleOutput] into [strCurrentLine] and test the [strToken]
As I said though, <COLOR color="#FF0000">maybe I got it wrong…</COLOR>

The only thing necessary for the triumph of evil is for good men to do nothing.”― Edmund Burke;
It's easy to die for an idea. It is way harder to LIVE for your idea! (Me)
Online now: No Back to the top

Post

Posted
Rating:
#5
Avatar
Regular
Philippe734 is in the usergroup ‘Regular’
Solved:
I was not on the right the way. In Process_Read() we need to use Line Input instead of Read for that context.

Code (gambas)

  1. hProc = Exec ["command"] For Read As "Contents"

Code (gambas)

  1. Public Sub Contents_Read()  
  2.   Dim sLine As String
  3.  
  4.     Line Input #hProc, sLine    
  5.   Until sLine = "textcondition"
  6.   sOutput = sLine
  7.  
  8.   hProc.Kill
  9.   hProc.Close

 Linux & Android enthusiast - France
Online now: No Back to the top

Post

Posted
Rating:
#6
Avatar
Regular
Serban is in the usergroup ‘Regular’

Philippe734 said

we need to use Line Input instead of Read for that context.
That is the point:
In the code I put there, and I mentioned "I SUPPOSED", the idea was to "Read Line", but the specifics of the output, were only a supposition.
Without a line formatted output, it's very difficult to "catch" a certain token, since the "one line" output is constantly changing.
If we have lines, it's easier, we can kill the process, once the token showed up. That spears CPU/RAM time.
The other approach, would require a loop (While/Wend) and reading recursively the current output, as it was generated at each iteration.
While the test condition is static, the test string changes continuously.
Problem is that I know nothing about how can you get out of the Shell/Exec the value of strOutput BEFORE the command ends. The test is otherwise, trivial.

Code (gambas)

  1. If InStr(strToken, strOutput) Then

… do whatever necessary

The only thing necessary for the triumph of evil is for good men to do nothing.”― Edmund Burke;
It's easy to die for an idea. It is way harder to LIVE for your idea! (Me)
Online now: No Back to the top
1 guest and 0 members have just viewed this.