Home > Enterprise >  How do I suppress output from a cat command that uses the os.system library in Python
How do I suppress output from a cat command that uses the os.system library in Python

Time:08-11

I have a Python 3 program that uses the os process to run the "cat" command.

This is the code fragment, it wirks great, but all the output ends up on the screeen.

os.system("cat *.txt | tee output.txt")

How can I suppress the output from appearing on the screen?

Thanks for any help or suggestions.

CodePudding user response:

Avoiding The Problem Altogether

tee writes to stdout. If you don't want to write to stdout, don't use tee:

os.system("cat -- *.txt >output.txt")

Redirecting Stdout Away

If you do want to use tee, you can explicitly redirect away its stdout:

os.system('cat -- *.txt | tee output.txt >/dev/null')

Using subprocess.run With stdout=subprocess.DEVNULL

If you don't want to modify the shell command to add a redirection within it, subprocess.run gives you enough power to specify redirections to perform before starting a shell:

import subprocess

subprocess.run('cat -- *.txt | tee output.txt', shell=True,
               stdout=subprocess.DEVNULL)

Using subprocess.run Without tee Or A Shell

...but it's more efficient and less prone to security issues if you just don't use a shell at all:

import subprocess, glob

subprocess.run(['cat', '--']   glob.glob('*.txt'),
               stdout=open('output.txt', 'w'))

Using subprocess.run With Tee, But Without A Shell

If you're up for not using a shell at all, but your real-world use case unconditionally includes some analogue to tee, the Python standard-library documentation describes how to accomplish this at https://docs.python.org/3/library/subprocess.html#replacing-shell-pipeline, as demonstrated below:

import subprocess, glob
p1 = subprocess.Popen(['cat', '--']   glob.glob('*.txt'), stdout=subprocess.PIPE)
p2 = subprocess.Popen(['tee', 'output.txt', stdin=p1.stdout, stdout=subprocess.DEVNULL)
p1.stdout.close()
p2.communicate()

CodePudding user response:

You shall take care about the default shell used by os.system

Try to execute this to check the shell used in background:

python3 -c 'import os; os.system("ps $$")'

You can change your code a little bit to force the bash shell and redirect the output to /dev/null:

os.system('/bin/bash -c "cat *.txt | tee output.txt &>/dev/null"')

Note that regardless of the technique (you could use subprocess module) the point is the background shell and the output redirection.

  • Related