Redirect stdout to a file in Python?
If you want to do the redirection within the Python script, setting sys.stdout
to a file object does the trick:
# for python3
import sys
with open('file', 'w') as sys.stdout:
print('test')
A far more common method is to use shell redirection when executing (same on Windows and Linux):
$ python3 foo.py > file
Python: stdout to both console and textfile including errors
If you are using bash (minimum version 4), you can run: ./mystdout |& tee output.txt
. Otherwise your suggestion ./mystdout 2>&1 | tee output.txt
should also work.
How to redirect output to a file and stdout
The command you want is named tee
:
foo | tee output.file
For example, if you only care about stdout:
ls -a | tee output.file
If you want to include stderr, do:
program [arguments...] 2>&1 | tee outfile
2>&1
redirects channel 2 (stderr/standard error) into channel 1 (stdout/standard output), such that both is written as stdout. It is also directed to the given output file as of the tee
command.
Furthermore, if you want to append to the log file, use tee -a
as:
program [arguments...] 2>&1 | tee -a outfile
How to output to the console and file?
I came up with this [untested]
import sys
class Tee(object):
def __init__(self, *files):
self.files = files
def write(self, obj):
for f in self.files:
f.write(obj)
f.flush() # If you want the output to be visible immediately
def flush(self) :
for f in self.files:
f.flush()
f = open('out.txt', 'w')
original = sys.stdout
sys.stdout = Tee(sys.stdout, f)
print "test" # This will go to stdout and the file out.txt
#use the original
sys.stdout = original
print "This won't appear on file" # Only on stdout
f.close()
print>>xyz
in python will expect a write()
function in xyz
. You could use your own custom object which has this. Or else, you could also have sys.stdout refer to your object, in which case it will be tee-ed even without >>xyz
.
How to redirect and append both standard output and standard error to a file with Bash
cmd >>file.txt 2>&1
Bash executes the redirects from left to right as follows:
>>file.txt
: Openfile.txt
in append mode and redirectstdout
there.2>&1
: Redirectstderr
to "wherestdout
is currently going". In this case, that is a file opened in append mode. In other words, the&1
reuses the file descriptor whichstdout
currently uses.
Redirecting stdout and stderr to file and console
Taking a cue from this blog post you could write a custom tee
function that distinguishes input by object type and writes to the corresponding output file. Something like this:
function Tee-Custom {
[CmdletBinding()]
Param(
[Parameter(
Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true
)]
[array]$InputObject,
[Parameter(Mandatory=$false)]
[string]$OutputLogfile,
[Parameter(Mandatory=$false)]
[string]$ErrorLogfile,
[Parameter(Mandatory=$false)]
[switch]$Append
)
Begin {
if (-not $Append.IsPresent) {
if ($OutputLogfile -and (Test-Path -LiteralPath $OutputLogfile)) {
Clear-Content -LiteralPath $OutputLogfile -Force
}
if ($ErrorLogfile -and (Test-Path -LiteralPath $ErrorLogfile)) {
Clear-Content -LiteralPath $ErrorLogfile -Force
}
}
}
Process {
$InputObject | ForEach-Object {
$params = @{'InputObject' = $_}
if ($_ -is [Management.Automation.ErrorRecord]) {
if ($ErrorLogfile) { $params['FilePath'] = $ErrorLogfile }
} else {
if ($OutputLogfile) { $params['FilePath'] = $OutputLogfile }
}
Tee-Object @params -Append
}
}
}
which could be used like this:
& program.exe 2>&1 | Tee-Custom -OutputLogfile 'out.log' -ErrorLogfile 'err.log' -Append
Related Topics
Django: Deploying an Application on Heroku with SQLite3 as the Database
Flask Application Traceback Doesn't Show Up in Server Log
Connecting Slots and Signals in Pyqt4 in a Loop
Inverting a Dictionary with List Values
How to Change an Image Size in Pygame
Error Message: 'Chromedriver' Executable Needs to Be Path
Pyinstaller Unable to Access Data Folder
Finding What Methods a Python Object Has
Explaining Python's '_Enter_' and '_Exit_'
Python Image Library Fails with Message "Decoder Jpeg Not Available" - Pil
How to Set the Current Working Directory
How to Create Nested Dict in Python
Putting an If-Elif-Else Statement on One Line
Python Sockets Error Typeerror: a Bytes-Like Object Is Required, Not 'Str' with Send Function