I want to run a Python script and save its console output to a file, while still being able to see the output in the console. For example, a "Hello World" script as simple as print('Hello World') would show Hello World in the console and also save this output to a file.
I was previously using pythonscript.py > console_output.txt to shell redirect, I can't see anything in the console with this solution (and for some reason, it no longer saves anything to the specified file, no idea why). This is a solution using Linux shell redirection, but now I would like to write a separate python script to do it.
I don't think I need any special error logging stuff. I'm currently using try: except blocks and just printing the Exception and then using that to find the error.
You can do you something like this:
def custom_print(message_to_print, log_file='output.txt'):
print(message_to_print)
with open(log_file, 'a') as of:
of.write(message_to_print + '\n')
This way you can use custom_print instead of print to be able to both see the result in the console and have the result appended to a log file.
Try tee command, for example: pythonscript.py | tee console_output.txt
Related
I would like to save the input code and the output result into a file. For example the following python code code.py:
print(2+2)
print(3+2)
to create a code-and-output.txt:
>>> print(2+2)
4
>>> print(3+2)
5
But I can not get it working. Basically, I want to code-and-output.txt to capture what would happen if I run interpreted python and run statements in python interactive environment (code + output).
Ways that I have tried so far:
Redirect stdout:
python code.py > code-and-output.txt
It only saves the output.
Redirect stdout and stdin:
python < code.py > code-and-output.txt
It does the same (only output).
nohup
nohup python code.py
The same problem: only output.
Script
script -q code-and-output.txt
python
print(2+2)
print(2+3)
ctr+d
ctr+d
It works but I need to do it manually. Moreover, it saves some garbage that I can not make them quiet with -q.
Bash Script
# bash-file.sh
python &
print(2+2)
print(2+3)
Does not work: commands run in console bash, not python. It does not work with & either: never ends python repl.
Using tty
open another terminal like /dev/pts/2 and send above bash-file.sh
cat bash-file.sh > /dev/pts/2
It just copies but does not run.
I am not interested in solutions like Jupyter and iPython. They have their own problems that does not address my requirement.
Any solution through linux commands (preferably) or python? Thank you.
Save this is as repl_sim.py in the same directory as your code.py:
with open("code.py", 'r') as input_file:
for line in input_file:
print(f">>> {line.strip()}")
eval(line)
Then run in your terminal with the following if you want to redirect the output to a text file named code-and-output.txt:
python repl_sim.py > code-and-output.txt
-OR-
Then run in your terminal with the following if you want to see the output as well as the make the text file matching:
python repl_sim.py | tee code-and-output.txt
It at least works for the example you provided as code.py.
Pure Python version of first option above so that you don't need shell redirect.
Save this code as repl_sim.py:
import contextlib
with open('code-and-output.txt', 'w') as f:
with contextlib.redirect_stdout(f):
with open("code.py", 'r') as input_file:
for line in input_file:
print(f">>> {line.strip()}")
eval(line)
Then run in your terminal with:
python repl_sim.py
That will result in code-and-output.txt with your desired content.
Contextlib use based on Raymond Hettinger's August 17th 2018 Tweet and contextlib.redirect_stdout() documentation
.
Trying to get robot framework to properly be able to validate the result of a basic .py file.
I have a simple Hello World python file in a resource directory.
My .robot file looks like this:
*** Settings ***
Library Process
*** Test Case ***
We should print to a command line.
${result}= run process python -c ../Resources/helloWorld.py
Should Be Equal ${result.stdout} Hello World.
The helloWorld.py file is just print("Hello World.")
Directory structure would look like this:
Root
-tests
--test.robot
-Resources
--hellowWorld.py
But when I execute the test I receive a fail with the result: != Hello World.
Found that it wasn't able to find the directory using relative path, ended up needing to use the full path.
stdout was just logging | FAIL |
So I logged the stderr and found that it was throwing a syntax error. After some trial and error of tweaking the path and escaping all my slashes, it was able to run how I was expecting it to.
First of all, I suggest you use "log" to see what your "${result}" is, I doubt that the robot can get the content that you printed in python. Second, I think you should try "Should Be Equal As Strings"
I have a large python script. It prints a bunch of output on my terminal console. The problem is the print is not happening altogether. Some print statements print one blob of statements together, then under that some other part of code prints some stuff. It goes on as long as the main loop runs.
Issue is I get the output as I want but all is getting printed on console as that is where we are running the python main script.
It would be very helpful if along with the print happening at console, I can get all the output in console in same format to a text file also for retention.
Again, there are bunch of print statements occurring in different parts of the whole script. So not sure how to retain the whole output of console in same format to a final text file.
If you want to do the redirection within the Python script, setting sys.stdout to a file object does the trick:
import sys
sys.stdout = open('file', 'w')
print('test')
A far more common method is to use shell redirection when executing (same on Windows and Linux):
$ python foo.py > file
Check this thread Redirect stdout to a file in Python?
Custom Print function for both console and file, replace all print with printing in the code.
outputFile = open('outputfile.log', 'w')
def printing(text):
print(text)
if outputFile:
outputFile.write(str(text))
you have to add file argument to the print() function
print('whatever', file = file_name)
I would rather go ahead with bash and use tee command. It redirects the output to a file too.
python -u my.py | tee my_file.txt
If your python script is file.py, Then use :
python3 file.py > output.txt
Or
python file.py > output.txt
Depending on your python version. This statement (>) will all the outputs of the program into the stdout to the file, output.txt
EDIT :
python3 file.py > output.txt;cat output.txt
The above line can be used to print the file output.txt after the program execution.
EDIT2 :
Another possible option to use a custom print function :
f = open('output.txt')
def custom_print(e = '\n',*s)
for i in s[:-1]:
print(i,end=' ')
print(s[-1],end = e)
f.write(s)
#Your code
#
f.close()
I am attempting to write a (Bash) shell script that wraps around a third-party python script and captures all output (errors and stdout) into a log file, and also restarts the script with a new batch of data each time it completes successfully. I'm doing this on a standard Linux distribution, but hopefully this solution can be platform-independent.
So here's a simplified version of the shell script, omitting everything except the logging:
#!/bin/bash
/home/me/script.py &>> /home/me/logfile
The problem is the third-party python script's output is mostly on a single line, which is being refreshed periodically (~every 90 seconds) by use of a carriage return ("\r"). Here's an example of the type of output I mean:
#!/usr/bin/env python3
import time
tracker = 1
print("This line is captured in the logfile because it ends with a newline")
while tracker < 5:
print(" This output isn't captured in the log file. Tracker = " + str(tracker),end="\r")
tracker += 1
time.sleep(1)
print("This line does get captured. Script is done. ")
How can I write a simple shell script to capture the output each time it is refreshed, or at least to periodically capture the current output as it would appear on the screen if I were running the script in the terminal?
Obviously I could try to modify the python script to change its output behavior, but the actual script I'm using is very complex and I think beyond my abilities to do that easily.
The program should have disabled this behavior when output is not a tty.
The output is already captured completely, it's just that you see all the updates at once when you cat the file. Open it in a text editor and see for yourself.
To make the file easier to work with, you can just replace the carriage returns with line feeds:
/home/me/script.py | tr '\r' '\n'
If the process normally produces output right away, but not with this command, you can disable Python's output buffering.
I have a python script that currently outputs a bunch of text to stdout (the terminal). It looks something like:
print "ABC"
print "CD"
print "QR"
methodCallToOtherCodeThatAlsoPrints()
# A bunch of other print lines...
Right now all of this output just goes to stdout; however, I want the output to be written to a file in addition to writing to the terminal. What is the best way to do this? Ideally I don't want to have to change all of the print statements (to another method call for instance), and I don't have access to some of the code is called to do the printing.
I was thinking, is there someway I can redirect print output to both stdout AND a file?
open a file and write your string in it:
with open('my_file' , 'w') as f:
f.write('your_string')
and if you want to redirect your output to a file use > in terminal after invoke the .py file :
$~ python my_file.py > save_file.txt