Clear terminal in Python
Question:
Does any standard “comes with batteries” method exist to clear the terminal screen from a Python script, or do I have to go curses (the libraries, not the words)?
Answers:
You could tear through the terminfo database, but the functions for doing so are in curses
anyway.
What about escape sequences?
print(chr(27) + "[2J")
python -c "from os import system; system('clear')"
If you are on a Linux/UNIX system then printing the ANSI escape sequence to clear the screen should do the job. You will also want to move cursor to the top of the screen. This will work on any terminal that supports ANSI.
import sys
sys.stderr.write("x1b[2Jx1b[H")
This will not work on Windows unless ANSI support has been enabled. There may be an equivalent control sequence for Windows, but I do not know.
you can make your own. this will not be dependent on your terminal, or OS type.
def clear(num):
for i in range(num): print
clear(80)
print "hello"
A simple and cross-platform solution would be to use either the cls
command on Windows, or clear
on Unix systems. Used with os.system
, this makes a nice one-liner:
import os
os.system('cls' if os.name == 'nt' else 'clear')
If all you need is to clear the screen, this is probably good enough. The problem is there’s not even a 100% cross platform way of doing this across linux versions. The problem is the implementations of the terminal all support slightly different things. I’m fairly sure that “clear” will work everywhere. But the more “complete” answer is to use the xterm control characters to move the cursor, but that requires xterm in and of itself.
Without knowing more of your problem, your solution seems good enough.
You could try to rely on clear but it might not be available on all Linux distributions. On windows use cls as you mentionned.
import subprocess
import platform
def clear():
subprocess.Popen( "cls" if platform.system() == "Windows" else "clear", shell=True)
clear()
Note: It could be considered bad form to take control of the terminal screen. Are you considering using an option? It would probably be better to let the user decide if he want to clear the screen.
A perhaps cheesy way to clear the screen, but one that will work on any platform I know of, is as follows:
for i in xrange(0,100):
print ""
This will clear 25 new lines:
def clear():
print(' n' * 25)
clear()
I use eclipse with pydev. I like the newline solution better than the for num in range . The for loop throws warnings, while the print newline doesn’t.
If you want to specify the number of newlines in the clear statement try this variation.
def clear(j):
print(' n' * j)
clear(25)
For Windows, on the interpreter command line only (not the GUI)! Simply type:
(Remember to use proper indentation with python):
import os
def clear():
os.system('cls')
Every time you type clear()
on the shell (command line), it will clear the screen on your shell. If you exit the shell, then you must redo the above to do it again as you open a new Python (command line) shell.
Note: Does not matter what version of Python you are using, explicitly (2.5, 2.7, 3.3 & 3.4).
By default, os.system("clear")
/os.system("cls")
will return an int type as 0.
We can completely clear the screen by assigning it to a variable and deleting that.
def clear():
if (os.name == 'nt'):
c = os.system('cls')
else:
c = os.system('clear')
del c # can also omit c totally
#clear()
This function works in gnome-terminal because, by default, it recognizes ANSI escape sequences. It gives you a CLEAN PROMPT rows_max
distance from the bottom of the terminal, but also precisely from where it was called. Gives you complete control over how much to clear.
def clear(rows=-1, rows_max=None, *, calling_line=True, absolute=None,
store_max=[]):
"""clear(rows=-1, rows_max=None)
clear(0, -1) # Restore auto-determining rows_max
clear(calling_line=False) # Don't clear calling line
clear(absolute=5) # Absolutely clear out to 5 rows up"""
from os import linesep
if rows_max and rows_max != -1:
store_max[:] = [rows_max, False]
elif not store_max or store_max[1] or rows_max == -1 or absolute:
try:
from shutil import get_terminal_size
columns_max, rows_max = get_terminal_size()
except ImportError:
columns_max, rows_max = 80, 24
if absolute is None:
store_max[:] = [rows_max, True]
if store_max:
if rows == -1:
rows = store_max[0]
elif isinstance(rows, float):
rows = round(store_max[0] * rows)
if rows > store_max[0] - 2:
rows = store_max[0] - 2
if absolute is None:
s = (' 33[1A' + ' ' * 30 if calling_line else '') + linesep * rows
else:
s = ' 33[{}A'.format(absolute + 2) + linesep
if absolute > rows_max - 2:
absolute = rows_max - 2
s += (' ' * columns_max + linesep) * absolute + ' ' * columns_max
rows = absolute
print(s + ' 33[{}A'.format(rows + 1))
Implementation:
clear() # Clear all, TRIES to automatically get terminal height
clear(800, 24) # Clear all, set 24 as terminal (max) height
clear(12) # Clear half of terminal below if 24 is its height
clear(1000) # Clear to terminal height - 2 (24 - 2)
clear(0.5) # float factor 0.0 - 1.0 of terminal height (0.5 * 24 = 12)
clear() # Clear to rows_max - 2 of user given rows_max (24 - 2)
clear(0, 14) # Clear line, reset rows_max to half of 24 (14-2)
clear(0) # Just clear the line
clear(0, -1) # Clear line, restore auto-determining rows_max
clear(calling_line=False) # Clear all, don't clear calling line
clear(absolute=5) # Absolutely clear out to 5 rows up
Parameters: rows
is the number of clear text rows to add between prompt and bottom of terminal, pushing everything up. rows_max
is the height of the terminal (or max clearing height) in text rows, and only needs to be set once, but can be reset at any time. *,
in the third parameter position means all following parameters are keyword only (e.g., clear(absolute=5)). calling_line=True
(default) works better in Interactive mode. calling_line=False
works better for text-based, terminal applications. absolute
was added to try to fix glitchy gap problems in Interactive mode after reducing size of terminal, but can also be used for terminal applications. store_max
is just for secret, “persistent” storage of rows_max
value; don’t explicitly use this parameter. (When an argument is not passed for store_max
, changing the list contents of store_max
changes this parameter’s default value. Hence, persistent storage.)
Portability: Sorry, this doesn’t work in IDLE, but it works >> VERY COOL << in Interactive mode in a terminal (console) that recognizes ANSI escape sequences. I only tested this in Ubuntu 13.10 using Python 3.3 in gnome-terminal. So I can only assume portability is dependant upon Python 3.3 (for the shutil.get_terminal_size()
function for BEST results) and ANSI recognition. The print(...)
function is Python 3. I also tested this with a simple, text-based, terminal Tic Tac Toe game (application).
For use in Interactive mode: First copy and paste the copy(...)
function in Interactive mode and see if it works for you. If so, then put the above function into a file named clear.py . In the terminal start python, with ‘python3’. Enter:
>>> import sys
>>> sys.path
['', '/usr/lib/python3.3', ...
Now drop the clear.py file into one of the path
directories listed so that Python can find it (don’t overwrite any existing files). To easily use from now on:
>>> from clear import clear
>>> clear()
>>> print(clear.__doc__)
clear(rows=-1, rows_max=None)
clear(0, -1) # Restore auto-determining rows_max
clear(calling_line=False) # Don't clear calling line
clear(absolute=5) # Absolutely clear out to 5 rows up
For use in a terminal application: Put the copy(...)
function into a file named clear.py in the same folder with your main.py file. Here is a working abstract (skeleton) example from a Tic Tac Toe game application (run from terminal prompt: python3 tictactoe.py):
from os import linesep
class TicTacToe:
def __init__(self):
# Clear screen, but not calling line
try:
from clear import clear
self.clear = clear
self.clear(calling_line=False)
except ImportError:
self.clear = False
self.rows = 0 # Track printed lines to clear
# ...
self.moves = [' '] * 9
def do_print(self, *text, end=linesep):
text = list(text)
for i, v in enumerate(text[:]):
text[i] = str(v)
text = ' '.join(text)
print(text, end=end)
self.rows += text.count(linesep) + 1
def show_board(self):
if self.clear and self.rows:
self.clear(absolute=self.rows)
self.rows = 0
self.do_print('Tic Tac Toe')
self.do_print(''' | |
{6} | {7} | {8}
| |
-----------
| |
{3} | {4} | {5}
| |
-----------
| |
{0} | {1} | {2}
| |'''.format(*self.moves))
def start(self):
self.show_board()
ok = input("Press <Enter> to continue...")
self.moves = ['O', 'X'] * 4 + ['O']
self.show_board()
ok = input("Press <Enter> to close.")
if __name__ == "__main__":
TicTacToe().start()
Explanation: do_print(...)
on line 19 is a version of print(...)
needed to keep track of how many new lines have been printed (self.rows
). Otherwise, you would have to self.rows += 1
all over the place where print(...)
is called throughout the entire program. So each time the board is redrawn by calling show_board()
the previous board is cleared out and the new board is printed exactly where it should be. Notice self.clear(calling_line=False)
on line 9 basically pushes everything up RELATIVE to the bottom of the terminal, but does not clear the original calling line. In contrast, self.clear(absolute=self.rows)
on line 29 absolutely clears out everything self.rows
distance upward, rather than just pushing everything upward relative to the bottom of the terminal.
Ubuntu users with Python 3.3: Put #!/usr/bin/env python3
on the very first line of the tictactoe.py file. Right click on the tictactoe.py file => Properties => Permissions tab => Check Execute: Allow executing file as program. Double click on the file => Click Run in Terminal button. If an open terminal’s current directory is that of the tictactoe.py file, you can also start the file with ./tictactoe.py
.
This works on all platforms and it does work in both Python 2 and 3.
def clear(number):
for i in range(number):
print(" ")
Then to clear just type clear(numberhere)
.
For Windows, Mac and Linux, you can use the following code:
import subprocess, platform
if platform.system()=="Windows":
if platform.release() in {"10", "11"}:
subprocess.run("", shell=True) #Needed to fix a bug regarding Windows 10; not sure about Windows 11
print("
Does any standard “comes with batteries” method exist to clear the terminal screen from a Python script, or do I have to go curses (the libraries, not the words)?
You could tear through the terminfo database, but the functions for doing so are in curses
anyway.
What about escape sequences?
print(chr(27) + "[2J")
python -c "from os import system; system('clear')"
If you are on a Linux/UNIX system then printing the ANSI escape sequence to clear the screen should do the job. You will also want to move cursor to the top of the screen. This will work on any terminal that supports ANSI.
import sys
sys.stderr.write("x1b[2Jx1b[H")
This will not work on Windows unless ANSI support has been enabled. There may be an equivalent control sequence for Windows, but I do not know.
you can make your own. this will not be dependent on your terminal, or OS type.
def clear(num):
for i in range(num): print
clear(80)
print "hello"
A simple and cross-platform solution would be to use either the cls
command on Windows, or clear
on Unix systems. Used with os.system
, this makes a nice one-liner:
import os
os.system('cls' if os.name == 'nt' else 'clear')
If all you need is to clear the screen, this is probably good enough. The problem is there’s not even a 100% cross platform way of doing this across linux versions. The problem is the implementations of the terminal all support slightly different things. I’m fairly sure that “clear” will work everywhere. But the more “complete” answer is to use the xterm control characters to move the cursor, but that requires xterm in and of itself.
Without knowing more of your problem, your solution seems good enough.
You could try to rely on clear but it might not be available on all Linux distributions. On windows use cls as you mentionned.
import subprocess
import platform
def clear():
subprocess.Popen( "cls" if platform.system() == "Windows" else "clear", shell=True)
clear()
Note: It could be considered bad form to take control of the terminal screen. Are you considering using an option? It would probably be better to let the user decide if he want to clear the screen.
A perhaps cheesy way to clear the screen, but one that will work on any platform I know of, is as follows:
for i in xrange(0,100):
print ""
This will clear 25 new lines:
def clear():
print(' n' * 25)
clear()
I use eclipse with pydev. I like the newline solution better than the for num in range . The for loop throws warnings, while the print newline doesn’t.
If you want to specify the number of newlines in the clear statement try this variation.
def clear(j):
print(' n' * j)
clear(25)
For Windows, on the interpreter command line only (not the GUI)! Simply type:
(Remember to use proper indentation with python):
import os
def clear():
os.system('cls')
Every time you type clear()
on the shell (command line), it will clear the screen on your shell. If you exit the shell, then you must redo the above to do it again as you open a new Python (command line) shell.
Note: Does not matter what version of Python you are using, explicitly (2.5, 2.7, 3.3 & 3.4).
By default, os.system("clear")
/os.system("cls")
will return an int type as 0.
We can completely clear the screen by assigning it to a variable and deleting that.
def clear():
if (os.name == 'nt'):
c = os.system('cls')
else:
c = os.system('clear')
del c # can also omit c totally
#clear()
This function works in gnome-terminal because, by default, it recognizes ANSI escape sequences. It gives you a CLEAN PROMPT rows_max
distance from the bottom of the terminal, but also precisely from where it was called. Gives you complete control over how much to clear.
def clear(rows=-1, rows_max=None, *, calling_line=True, absolute=None,
store_max=[]):
"""clear(rows=-1, rows_max=None)
clear(0, -1) # Restore auto-determining rows_max
clear(calling_line=False) # Don't clear calling line
clear(absolute=5) # Absolutely clear out to 5 rows up"""
from os import linesep
if rows_max and rows_max != -1:
store_max[:] = [rows_max, False]
elif not store_max or store_max[1] or rows_max == -1 or absolute:
try:
from shutil import get_terminal_size
columns_max, rows_max = get_terminal_size()
except ImportError:
columns_max, rows_max = 80, 24
if absolute is None:
store_max[:] = [rows_max, True]
if store_max:
if rows == -1:
rows = store_max[0]
elif isinstance(rows, float):
rows = round(store_max[0] * rows)
if rows > store_max[0] - 2:
rows = store_max[0] - 2
if absolute is None:
s = (' 33[1A' + ' ' * 30 if calling_line else '') + linesep * rows
else:
s = ' 33[{}A'.format(absolute + 2) + linesep
if absolute > rows_max - 2:
absolute = rows_max - 2
s += (' ' * columns_max + linesep) * absolute + ' ' * columns_max
rows = absolute
print(s + ' 33[{}A'.format(rows + 1))
Implementation:
clear() # Clear all, TRIES to automatically get terminal height
clear(800, 24) # Clear all, set 24 as terminal (max) height
clear(12) # Clear half of terminal below if 24 is its height
clear(1000) # Clear to terminal height - 2 (24 - 2)
clear(0.5) # float factor 0.0 - 1.0 of terminal height (0.5 * 24 = 12)
clear() # Clear to rows_max - 2 of user given rows_max (24 - 2)
clear(0, 14) # Clear line, reset rows_max to half of 24 (14-2)
clear(0) # Just clear the line
clear(0, -1) # Clear line, restore auto-determining rows_max
clear(calling_line=False) # Clear all, don't clear calling line
clear(absolute=5) # Absolutely clear out to 5 rows up
Parameters: rows
is the number of clear text rows to add between prompt and bottom of terminal, pushing everything up. rows_max
is the height of the terminal (or max clearing height) in text rows, and only needs to be set once, but can be reset at any time. *,
in the third parameter position means all following parameters are keyword only (e.g., clear(absolute=5)). calling_line=True
(default) works better in Interactive mode. calling_line=False
works better for text-based, terminal applications. absolute
was added to try to fix glitchy gap problems in Interactive mode after reducing size of terminal, but can also be used for terminal applications. store_max
is just for secret, “persistent” storage of rows_max
value; don’t explicitly use this parameter. (When an argument is not passed for store_max
, changing the list contents of store_max
changes this parameter’s default value. Hence, persistent storage.)
Portability: Sorry, this doesn’t work in IDLE, but it works >> VERY COOL << in Interactive mode in a terminal (console) that recognizes ANSI escape sequences. I only tested this in Ubuntu 13.10 using Python 3.3 in gnome-terminal. So I can only assume portability is dependant upon Python 3.3 (for the shutil.get_terminal_size()
function for BEST results) and ANSI recognition. The print(...)
function is Python 3. I also tested this with a simple, text-based, terminal Tic Tac Toe game (application).
For use in Interactive mode: First copy and paste the copy(...)
function in Interactive mode and see if it works for you. If so, then put the above function into a file named clear.py . In the terminal start python, with ‘python3’. Enter:
>>> import sys
>>> sys.path
['', '/usr/lib/python3.3', ...
Now drop the clear.py file into one of the path
directories listed so that Python can find it (don’t overwrite any existing files). To easily use from now on:
>>> from clear import clear
>>> clear()
>>> print(clear.__doc__)
clear(rows=-1, rows_max=None)
clear(0, -1) # Restore auto-determining rows_max
clear(calling_line=False) # Don't clear calling line
clear(absolute=5) # Absolutely clear out to 5 rows up
For use in a terminal application: Put the copy(...)
function into a file named clear.py in the same folder with your main.py file. Here is a working abstract (skeleton) example from a Tic Tac Toe game application (run from terminal prompt: python3 tictactoe.py):
from os import linesep
class TicTacToe:
def __init__(self):
# Clear screen, but not calling line
try:
from clear import clear
self.clear = clear
self.clear(calling_line=False)
except ImportError:
self.clear = False
self.rows = 0 # Track printed lines to clear
# ...
self.moves = [' '] * 9
def do_print(self, *text, end=linesep):
text = list(text)
for i, v in enumerate(text[:]):
text[i] = str(v)
text = ' '.join(text)
print(text, end=end)
self.rows += text.count(linesep) + 1
def show_board(self):
if self.clear and self.rows:
self.clear(absolute=self.rows)
self.rows = 0
self.do_print('Tic Tac Toe')
self.do_print(''' | |
{6} | {7} | {8}
| |
-----------
| |
{3} | {4} | {5}
| |
-----------
| |
{0} | {1} | {2}
| |'''.format(*self.moves))
def start(self):
self.show_board()
ok = input("Press <Enter> to continue...")
self.moves = ['O', 'X'] * 4 + ['O']
self.show_board()
ok = input("Press <Enter> to close.")
if __name__ == "__main__":
TicTacToe().start()
Explanation: do_print(...)
on line 19 is a version of print(...)
needed to keep track of how many new lines have been printed (self.rows
). Otherwise, you would have to self.rows += 1
all over the place where print(...)
is called throughout the entire program. So each time the board is redrawn by calling show_board()
the previous board is cleared out and the new board is printed exactly where it should be. Notice self.clear(calling_line=False)
on line 9 basically pushes everything up RELATIVE to the bottom of the terminal, but does not clear the original calling line. In contrast, self.clear(absolute=self.rows)
on line 29 absolutely clears out everything self.rows
distance upward, rather than just pushing everything upward relative to the bottom of the terminal.
Ubuntu users with Python 3.3: Put #!/usr/bin/env python3
on the very first line of the tictactoe.py file. Right click on the tictactoe.py file => Properties => Permissions tab => Check Execute: Allow executing file as program. Double click on the file => Click Run in Terminal button. If an open terminal’s current directory is that of the tictactoe.py file, you can also start the file with ./tictactoe.py
.
This works on all platforms and it does work in both Python 2 and 3.
def clear(number):
for i in range(number):
print(" ")
Then to clear just type clear(numberhere)
.
For Windows, Mac and Linux, you can use the following code:
import subprocess, platform
if platform.system()=="Windows":
if platform.release() in {"10", "11"}:
subprocess.run("", shell=True) #Needed to fix a bug regarding Windows 10; not sure about Windows 11
print("