LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 03-25-2022, 05:30 AM   #1
centguy
Member
 
Registered: Feb 2008
Posts: 627
Blog Entries: 1

Rep: Reputation: 48
python output using "python script > result" shows that the sequence of printing is haphazard


I have a python script "script.py".

When I run "python script.py" the output on the screen seems to be in sequence.

But if I direct the output to a file via
"python script.py > a-file", the sequence is definitely messed up.

How to preserve the sequence to allow debugging?

The printings from script.py are from print("..."), os.system("cat a-list"),
and os.system("a-Fortran-binary"), where a-Fortran-binary printing output to the screen.

Python is giving me so many surprises..
 
Old 03-25-2022, 05:32 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,901

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
would be nice to see some details or example.
Do you mean the output of the two commands are mixed?
 
Old 03-25-2022, 10:10 AM   #3
centguy
Member
 
Registered: Feb 2008
Posts: 627

Original Poster
Blog Entries: 1

Rep: Reputation: 48
First write a simple Fortran program
:

Quote:
$ cat fort.f90
program simple


write(*,*) 'I am in Fortran!'

end program
Next prepare a simple test.py:

PHP Code:
cat test.py
import os


= [1,2,3]

print(
"L is ",L)

with open("Lfile","w") as f:

       
f.write("L is %d %d %d\n"%(L[0],L[1],L[2]))

os.system("cat Lfile")

os.system("./fortbin"
Then prepare a Makefile:

PHP Code:
cat Makefile 
all
:
    
gfortran fort.f90 -o fortbin
    python test
.py
    
echo "----separator----"
    
python test.py savepy-output
    cat savepy
-output 
Now type make:

Quote:

$ make
gfortran fort.f90 -o fortbin
python test.py
L is [1, 2, 3]
L is 1 2 3
I am in Fortran!
echo "----separator----"
----separator----
python test.py > savepy-output
cat savepy-output
L is 1 2 3
I am in Fortran!
L is [1, 2, 3]

See that `L is [1, 2, 3]' appears on the first line in first instance and
the third line in the second instance.


Probably python is not designed to do this kind of things.

Last edited by centguy; 03-25-2022 at 10:12 AM.
 
Old 03-25-2022, 11:16 AM   #4
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,614

Rep: Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554

That's not a great example - could have been simplified further to highlight the issue.

Anyway, the docs are a bit vague, but it appears to be because os.system is asynchronous, and you need an explicit os.wait() call to change that.

Or you could replace it with subprocess.call, which will: "Run the command described by args. Wait for command to complete, then return the returncode attribute."


Last edited by boughtonp; 03-25-2022 at 11:18 AM.
 
Old 03-25-2022, 10:55 PM   #5
centguy
Member
 
Registered: Feb 2008
Posts: 627

Original Poster
Blog Entries: 1

Rep: Reputation: 48
>That's not a great example - could have been simplified further to highlight the issue.

i have used all I know to cook up this example.
 
Old 03-25-2022, 11:23 PM   #6
centguy
Member
 
Registered: Feb 2008
Posts: 627

Original Poster
Blog Entries: 1

Rep: Reputation: 48
I find it useful to flush the python output first
using

sys.stdout.flush()

A bit clumsy but it works.
 
Old 03-25-2022, 11:38 PM   #7
centguy
Member
 
Registered: Feb 2008
Posts: 627

Original Poster
Blog Entries: 1

Rep: Reputation: 48
Actually there are better options:

1. add flush=True so that we have print(any_string,flush=True)

2. Option 1 gets a bit tiring since we have to put flush=True in every single print statement.
To avoid it, ask python not to buffer using "-u" option.

So we need to do "python -u script.py"

option2 seems better since it involves the least of work but we have to remember to use -u.
 
Old 03-26-2022, 09:18 AM   #8
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,614

Rep: Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554

As per "python --help" instead of passing "-u" every time you can set an environment variable "PYTHONUNBUFFERED=x"; put it in a startup file and you don't need to remember it.

Not sure this is related to your question though, unless you're saying that preventing buffering has the effect of enforcing atomicity in the os.system calls?


Last edited by boughtonp; 03-26-2022 at 09:19 AM.
 
1 members found this post helpful.
Old 03-27-2022, 03:53 AM   #9
centguy
Member
 
Registered: Feb 2008
Posts: 627

Original Poster
Blog Entries: 1

Rep: Reputation: 48
PYTHONUNBUFFERED=x

is a good idea. Thanks!
 
Old 03-28-2022, 12:42 AM   #10
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,901

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
Quote:
Originally Posted by centguy View Post
Actually there are better options:

1. add flush=True so that we have print(any_string,flush=True)

2. Option 1 gets a bit tiring since we have to put flush=True in every single print statement.
To avoid it, ask python not to buffer using "-u" option.

So we need to do "python -u script.py"

option2 seems better since it involves the least of work but we have to remember to use -u.
In case of asynchronous calls non of these options are correct: the order of the execution is unpredictable. Adding flush=True or -u will not change it at all.
But os.system itself is not an async call, it will use wait for the end of the execution, so only these buffers caused this issue (that's why it helped in this case).

Last edited by pan64; 03-28-2022 at 12:55 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
am not getting any result when am using 'if', without getting result for below script alavala53 Linux - General 3 10-25-2012 06:00 PM
LXer: Haphazard proxy support in Linux programs LXer Syndicated Linux News 0 11-29-2011 09:00 AM
[SOLVED] Grep for the result of a command within the result of another command jasonws Programming 6 11-18-2010 02:39 PM
printing hh in hh:mm using "awk '{FS=":";print $1}'" misses first line of output!! mayankmehta83 Linux - Newbie 2 12-03-2009 02:55 AM
Help With Java Problem Please"""""""""""" suemcholan Linux - Newbie 1 04-02-2008 06:02 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 12:39 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration