Cómo obtener el ancho de la ventana de la consola de Linux en Python
¿Hay alguna forma en Python de determinar mediante programación el ancho de la consola? Me refiero a la cantidad de caracteres que caben en una línea sin ajustarse, no al ancho de píxeles de la ventana.
Editar
Buscando una solución que funcione en Linux
No estoy seguro de por qué está en el módulo shutil
, pero llegó allí en Python 3.3. Ver:
Consultar el tamaño del terminal de salida.
>>> import shutil
>>> shutil.get_terminal_size((80, 20)) # pass fallback
os.terminal_size(columns=87, lines=23) # returns a named-tuple
Hay una implementación de bajo nivel en el módulo del sistema operativo. Multiplataforma: funciona en Linux, Mac OS y Windows, probablemente en otros sistemas similares a Unix. También hay un backport, aunque ya no es relevante.
import os
rows, columns = os.popen('stty size', 'r').read().split()
utiliza el comando 'stty size' que, según un hilo de la lista de correo de Python, es razonablemente universal en Linux. Abre el comando 'tamaño stty' como un archivo, lo 'lee' y utiliza una división de cadena simple para separar las coordenadas.
A diferencia del valor os.environ["COLUMNS"] (al que no puedo acceder a pesar de usar bash como mi shell estándar), los datos también estarán actualizados, mientras que creo que os.environ["COLUMNS"] El valor solo sería válido durante el momento del lanzamiento del intérprete de Python (supongamos que el usuario cambió el tamaño de la ventana desde entonces).
(Vea la respuesta de @GringoSuave sobre cómo hacer esto en Python 3.3+)
usar
import console
(width, height) = console.getTerminalSize()
print "Your terminal's width is: %d" % width
EDITAR : oh, lo siento. Esa no es una biblioteca estándar de Python, aquí está la fuente de console.py (no sé de dónde es).
El módulo parece funcionar así: comprueba si termcap
está disponible y cuando sí. Utiliza eso; si no, verifica si el terminal admite una ioctl
llamada especial y eso no funciona, también verifica las variables de entorno que algunos shells exportan para eso. Probablemente esto sólo funcionará en UNIX.
def getTerminalSize():
import os
env = os.environ
def ioctl_GWINSZ(fd):
try:
import fcntl, termios, struct, os
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
'1234'))
except:
return
return cr
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
### Use get(key[, default]) instead of a try/catch
#try:
# cr = (env['LINES'], env['COLUMNS'])
#except:
# cr = (25, 80)
return int(cr[1]), int(cr[0])
El código anterior no arrojó el resultado correcto en mi Linux porque winsize-struct tiene 4 cortos sin firmar, no 2 cortos firmados:
def terminal_size():
import fcntl, termios, struct
h, w, hp, wp = struct.unpack('HHHH',
fcntl.ioctl(0, termios.TIOCGWINSZ,
struct.pack('HHHH', 0, 0, 0, 0)))
return w, h
hp y hp deben contener el ancho y alto de los píxeles, pero no lo hacen.