[Tutor] Interacting with stderr

Crush crushed26 at gmail.com
Sun Aug 31 15:25:34 CEST 2014


Alan said, 

"... you are reassigning p in the middle of a loop that 
depends on p. That's usually not a good idea..."

If not what I changed my code to, then I reckon I do not understand what he is suggesting I do. 

I have to reparse stderr, each time test_loop.sh is executed the content of stderr is different i.e. frames, bitrate, time running, etc. Picture, stderr out is being printed to the screen as a running log while the machine is decoding. The frames, time, etc. are counting up. If it has been decoding for 3 days, the the frames, time, etc. will reflect this. 

As far as killing off every avconv and bmdplay process, that is exactly what I need to do if they exist before I execute test_loop. I need a "clean slate" so-to-speak before each execution. 

Again, my code works so far in the lab, but I havent tested it with a live broadcast yet. I figured it would not work the same while testing live and I was anticipating changes would need to be made like what you suggested...

"This function won't work as you intend. Specificly, the "if" test is wrong. You want to change:
if proc.name == process1 and process2:
if proc.name in (process1, process2):"

Psutil.Popen works just fine. And I will remove "out, err = p.communicate()" as you are are correct, it is not being used. 

Yes the rest of my code does in fact work fine. Would you be willing to Teamviewer into my machine, so you can see a healthy decoding? This would give you a better understanding of what I am trying to accomplish. 

Thank you, 

Bo

>> On Aug 31, 2014, at 1:22 AM, Cameron Simpson <cs at zip.com.au> wrote:
>> 
>> On 30Aug2014 22:32, Crush <crushed26 at gmail.com> wrote:
>> Thank you Allan for your criticism. Please see the below changes. As far as the embedded loops, I know no other way to achieve the same out come.
> 
> Regrettably I've lost Alan's email on that (I had it:-).
> 
> It looks like you've taken he concern over nested use of p.stderr too literally. It loops like you avoid using the same stderr by restarting "test_loop.sh" in the inner loops and reparsing their error outputs. I'm fairly sure that is not what Alan intended and also not what you want to be doing.  Please explain your thinking here.
> 
> Regarding nested loops on the same iterable:
> 
> It is ok to nested use of an iterator, with some caution. The typical use case is some sort of nesting parse of the output. For example, if you were looking for the word "Segmentation", and then intending to act specially on all following lines until some marker. Another gleaming example that springs to mind would be gathering up python stack traces (multiline outputs) in some error log.
> 
> You'd fairly naturally end up with code a bit like this:
> 
> for line in p.stderr:
>   if "Segemntation" in line:
>     # ok, found the start line
>     for inner_line in p.stderr:
>       if "end segemntation marker" in inner_line:
>         break
>       ... do something with inner_line
> 
> That essentially has the effect that all the lines from "Segmentation" to "end segemntation marker" are processed specially by the inner loop, and after you see the end marker you return to the outer loop, looking for the next occurence of "Segmentation".
> 
> There is really only one pitfall with this, and that is the possibility that the end marker line is itself important.
> 
> Imagine you had two inner loops, one for the "Segmentation" section and another to handle some other section, like this:
> 
> for line in p.stderr:
>   if "Segemntation" in line:
>     # ok, found the start line
>     ... do the "Segmentation" section ...
>   elif "other-section" in line:
>     # ok, found the start line
>     ... do the "other-section" section ...
>   else:
>     # boring line, report it or discard it etc
> 
> Simple and straight forward, yes? It will nicely handly input like this:
> 
>  blah
>  blah
>  begin Segmentation
>>> stuff
>>> more stuff
>  end segmentation marker
>  blah
>  blah
>  begin other-section
>>> other stuff
>>> even more other stuff
>  end the other section
>  blah
> 
> However, consider the case where the end marker for the "Segmentation" section is not some special line generated by the "Segmentation" event, but simply some line that is not a match. Like the beginning of an "other-section" section. Eg:
> 
>  blah
>  blah
>  begin Segmentation
>>> stuff
>>> more stuff
>  begin other-section
>>> other stuff
>>> even more other stuff
>  blah
> 
> With input like that, the "end of section" line is itself an important line that needs to be considered. But the loop as written "consumes" the marker line, and it is not available for recognition on the next outer loop pass (because that fetches the next line).
> 
> This is where nested loops on the same iterable can have an issue. There are several things you can do about it depending on your code and your preferences.  
>> def kill_proc(process1, process2):
>> i = psutil.Popen(["ps", "cax"], stdout=PIPE)
>> out, err = i.communicate()
>> for proc in psutil.process_iter():
>>     if proc.name == process1 and process2:
>>         proc.kill()
> 
> This function won't work as you intend. Specificly, the "if" test is wrong. You want to change:
> 
> if proc.name == process1 and process2:
> 
> into:
> 
> if proc.name == process1 and or proc.name == process2:
> 
> or perhaps:
> 
> if proc.name in (process1, process2):
> 
> and your psutil.Popen call looks... confused. Popen is a subprocess function, not part of psutil (I think). And you don't use either "out" or "err" after you collect them, so why use .communicate?
> 
> Also, this will kill _every_ instance of mbplay and avconv, not just the ones you started. You would be better off just killing your own.
> 
> The rest of your code's function is not clear to me. Does it work?
> 
> Cheers,
> Cameron Simpson <cs at zip.com.au>


More information about the Tutor mailing list