Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
蜕变的菜鸟
glances
提交
878ec549
G
glances
项目概览
蜕变的菜鸟
/
glances
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
glances
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
878ec549
编写于
12月 13, 2011
作者:
N
nicolargo
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
version 1.3
上级
f31660e5
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
209 addition
and
36 deletion
+209
-36
Makefile.am
Makefile.am
+1
-1
Makefile.in
Makefile.in
+1
-1
NEWS
NEWS
+10
-3
README
README
+3
-3
TODO
TODO
+1
-1
configure.ac
configure.ac
+2
-1
man/Makefile.am
man/Makefile.am
+1
-0
man/glances.1
man/glances.1
+48
-0
setup.py
setup.py
+1
-1
src/glances.py
src/glances.py
+141
-25
未找到文件。
Makefile.am
浏览文件 @
878ec549
## Process this file with automake to produce Makefile.in
## Created by Anjuta
SUBDIRS
=
src
SUBDIRS
=
src
man
glancesdocdir
=
${prefix}
/doc/glances
glancesdoc_DATA
=
\
...
...
Makefile.in
浏览文件 @
878ec549
...
...
@@ -211,7 +211,7 @@ target_alias = @target_alias@
top_build_prefix
=
@top_build_prefix@
top_builddir
=
@top_builddir@
top_srcdir
=
@top_srcdir@
SUBDIRS
=
src
SUBDIRS
=
src
man
glancesdocdir
=
${prefix}
/doc/glances
glancesdoc_DATA
=
\
README
\
...
...
NEWS
浏览文件 @
878ec549
Version 1.2.x
=============
Version 1.3
===========
* Add file system stats (total and used space)
* Adapt unit dynamicaly (K, M, G)
* Add man page (Thanks to Edouard Bourguignon)
Version 1.2
===========
* Resize the terminal and the windows are adapted dynamicaly
* Refresh screen instantanetly when a key is pressed
Version 1.1.
x
Version 1.1.
3
=============
* Add disk IO monitoring
...
...
README
浏览文件 @
878ec549
...
...
@@ -14,12 +14,12 @@ Glances is developed in Python and uses the python-statgrab lib.
Get the latest version:
$ wget https://github.com/downloads/nicolargo/glances/glances-1.
2
.tar.gz
$ wget https://github.com/downloads/nicolargo/glances/glances-1.
3
.tar.gz
Glances use a standard GNU style installer:
$ tar zxvf glances-1.
2
.tar.gz
$ cd glances-1.
2
$ tar zxvf glances-1.
3
.tar.gz
$ cd glances-1.
3
$ ./configure
$ make
$ sudo make install
...
...
TODO
浏览文件 @
878ec549
-
Crach when a terminal is resized with a size < 80x24
-
Packaging for Linux / BSD distribution (need contributors)
configure.ac
浏览文件 @
878ec549
dnl Process this file with autoconf to produce a configure script.
dnl Created by Anjuta application wizard.
AC_INIT(Glances, 1.
2
, , glances)
AC_INIT(Glances, 1.
3
, , glances)
AC_CONFIG_HEADERS([config.h])
...
...
@@ -22,5 +22,6 @@ dnl AX_PYTHON_MODULE([statgrab],[needed])
AC_OUTPUT([
Makefile
src/Makefile
man/Makefile
])
man/Makefile.am
0 → 100644
浏览文件 @
878ec549
man_MANS
=
glances.1
man/glances.1
0 → 100644
浏览文件 @
878ec549
.TH glances 1 "December 13, 2011" "version 0.1" "USER COMMANDS"
.SH NAME
glances \- CLI curses based monitoring tool
.SH SYNOPSIS
.B glances
[\-h] [\-t refresh] [\-v]
.SH DESCRIPTION
Glances is a free (LGPL) curses-based monitoring tool which aims to present a maximum of information
in a minimum of space, ideally to fit in a classical 80x24 terminal. Glances can adapt dynamicaly the
displayed informations depending on the terminal size.
.PP
This tool is written in Python and uses pystatgrab to fetch the statistical values from key elements.
.PP
You can use the following keys to sort the processesi list:
.PP
'a' to set the automatic mode. The process list is sorted automatically
.PP
'c' the processes list is sorted by CPU consomption
.PP
'm' the processes list is sorted by process size
.PP
'q' Exit
.PP
The current version grab the following stats: CPU, Load, Memory, Network rate, Disk IO, file system,
process number and details.
.SH OPTIONS
.TP
.TP
\-h
Display the syntax and exit
.TP
\-t
Set the refresh time in second default is 1
.TP
-v
Display the version and exit
.SH EXAMPLES
.TP
Refresh information every 5 seconds:
.B glances
\-t 5
.PP
.SH EXIT STATUS
glances returns a zero exit status if it succeeds to print/grab information.
.PP
It returns 2 if it fails to parse its options (missing arguments, invalid value, etc).
.SH AUTHOR
Glances is written by Nicolargo (contact@nicolargo.com).
setup.py
浏览文件 @
878ec549
...
...
@@ -11,7 +11,7 @@ def read(fname):
return
open
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
fname
)).
read
()
setup
(
name
=
'Glances'
,
version
=
'1.
2
'
,
version
=
'1.
3
'
,
description
=
'CLI curses-based monitoring tool'
,
author
=
'Nicolas Hennion'
,
author_email
=
'nicolas@nicolargo.com'
,
...
...
src/glances.py
浏览文件 @
878ec549
...
...
@@ -33,7 +33,7 @@ import statgrab
#==================
# The glances version id
__version__
=
"1.
2
"
__version__
=
"1.
3
"
# Class
#======
...
...
@@ -50,6 +50,65 @@ class Timer():
return
time
.
time
()
>
self
.
target
class
glancesGrabFs
():
"""
Get FS stats: idem as structure http://www.i-scream.org/libstatgrab/docs/sg_get_fs_stats.3.html
"""
def
__init__
(
self
):
self
.
__update__
()
def
__update__
(
self
):
"""
Update the stats
"""
# Reset the list
self
.
fs_list
=
[]
# Ignore the following fs
ignore_fsname
=
(
'none'
,
'gvfs-fuse-daemon'
,
'fusectl'
)
ignore_fstype
=
(
'binfmt_misc'
,
'devpts'
,
'iso9660'
,
'none'
,
'proc'
,
'sysfs'
,
'usbfs'
)
# Open the current mounted FS
mtab
=
open
(
"/etc/mtab"
,
"r"
)
for
line
in
mtab
.
readlines
():
if
line
.
split
()[
0
]
in
ignore_fsname
:
continue
if
line
.
split
()[
2
]
in
ignore_fstype
:
continue
# Get FS stats
fs_current
=
{}
fs_name
=
self
.
__getmount__
(
line
.
split
()[
1
])
fs_stats
=
os
.
statvfs
(
fs_name
)
# Build the list
fs_current
[
'device_name'
]
=
str
(
line
.
split
()[
0
])
fs_current
[
'fs_type'
]
=
str
(
line
.
split
()[
2
])
fs_current
[
'mnt_point'
]
=
str
(
fs_name
)
fs_current
[
'size'
]
=
float
(
fs_stats
.
f_blocks
)
*
long
(
fs_stats
.
f_frsize
)
fs_current
[
'used'
]
=
float
(
fs_stats
.
f_blocks
-
fs_stats
.
f_bfree
)
*
long
(
fs_stats
.
f_frsize
)
fs_current
[
'avail'
]
=
float
(
fs_stats
.
f_bfree
)
*
long
(
fs_stats
.
f_frsize
)
self
.
fs_list
.
append
(
fs_current
)
mtab
.
close
()
def
__getmount__
(
self
,
path
):
"""
Return the real root path of a file
Exemple: /home/nicolargo can return /home or /
"""
path
=
os
.
path
.
realpath
(
os
.
path
.
abspath
(
path
))
while
path
!=
os
.
path
.
sep
:
if
os
.
path
.
ismount
(
path
):
return
path
path
=
os
.
path
.
abspath
(
os
.
path
.
join
(
path
,
os
.
pardir
))
return
path
def
get
(
self
):
self
.
__update__
()
return
self
.
fs_list
class
glancesStats
():
"""
This class store, update and give the libstatgrab stats
...
...
@@ -63,6 +122,10 @@ class glancesStats():
# Init libstatgrab
if
not
statgrab
.
sg_init
():
print
"Error: Can not init the libstatgrab library.
\n
"
# Init the interfac fs stats
self
.
glancesgrabfs
=
glancesGrabFs
()
# Do the first update
self
.
__update__
()
...
...
@@ -81,8 +144,8 @@ class glancesStats():
self
.
memswap
=
statgrab
.
sg_get_swap_stats
()
self
.
network
=
statgrab
.
sg_get_network_io_stats_diff
()
self
.
diskio
=
statgrab
.
sg_get_disk_io_stats_diff
()
#
BUG: https://bugs.launchpad.net/ubuntu/+source/libstatgrab/+bug/886783
# TODO: self.fs = statgrab.sg_get_fs_stats
()
#
Replace the bugged self.fs = statgrab.sg_get_fs_stats()
self
.
fs
=
self
.
glancesgrabfs
.
get
()
self
.
processcount
=
statgrab
.
sg_get_process_count
()
self
.
process
=
statgrab
.
sg_get_process_stats
()
self
.
now
=
datetime
.
datetime
.
now
()
...
...
@@ -129,6 +192,10 @@ class glancesStats():
def
getDiskIO
(
self
):
return
self
.
diskio
def
getFs
(
self
):
return
self
.
fs
def
getProcessCount
(
self
):
return
self
.
processcount
...
...
@@ -175,7 +242,8 @@ class glancesScreen():
self
.
load_x
=
20
;
self
.
load_y
=
3
self
.
mem_x
=
41
;
self
.
mem_y
=
3
self
.
network_x
=
0
;
self
.
network_y
=
9
self
.
diskio_x
=
0
;
self
.
diskio_y
=
16
self
.
diskio_x
=
0
;
self
.
diskio_y
=
-
1
self
.
fs_x
=
0
;
self
.
fs_y
=
-
1
self
.
process_x
=
30
;
self
.
process_y
=
9
self
.
now_x
=
79
;
self
.
now_y
=
3
self
.
caption_x
=
0
;
self
.
caption_y
=
3
...
...
@@ -210,7 +278,6 @@ class glancesScreen():
self
.
if90pc_color
=
curses
.
color_pair
(
2
)
|
curses
.
A_BOLD
# Init window
#self.term_window = self.screen.subwin(self.term_h, self.term_w, 0, 0)
self
.
term_window
=
self
.
screen
.
subwin
(
0
,
0
)
# Init refresh time
...
...
@@ -228,6 +295,24 @@ class glancesScreen():
def
getProcessSortedBy
(
self
):
return
self
.
__process_sortedby
def
__autoUnit
(
self
,
val
):
"""
Convert val to string and concatenate the good unit
Exemples:
960 -> 960
142948 -> 143K
560745673 -> 561M
...
"""
if
val
>=
1073741824L
:
return
"%.1fG"
%
(
val
/
1073741824L
)
elif
val
>=
1048576L
:
return
"%.1fM"
%
(
val
/
1048576L
)
elif
val
>=
1024
:
return
"%.1fK"
%
(
val
/
1024
)
else
:
return
str
(
int
(
val
))
def
__getColor
(
self
,
current
=
0
,
max
=
100
):
# If current > 50% of max then color = self.if50pc_color / A_DIM
...
...
@@ -300,8 +385,9 @@ class glancesScreen():
screen
.
displayCpu
(
stats
.
getCpu
())
screen
.
displayLoad
(
stats
.
getLoad
())
screen
.
displayMem
(
stats
.
getMem
(),
stats
.
getMemSwap
())
screen
.
displayNetwork
(
stats
.
getNetwork
())
screen
.
displayDiskIO
(
stats
.
getDiskIO
())
net_count
=
screen
.
displayNetwork
(
stats
.
getNetwork
())
disk_count
=
screen
.
displayDiskIO
(
stats
.
getDiskIO
(),
net_count
)
screen
.
displayFs
(
stats
.
getFs
(),
net_count
+
disk_count
)
screen
.
displayProcess
(
stats
.
getProcessCount
(),
stats
.
getProcessList
(
screen
.
getProcessSortedBy
()))
screen
.
displayCaption
()
screen
.
displayNow
(
stats
.
getNow
())
...
...
@@ -376,13 +462,13 @@ class glancesScreen():
if
((
screen_y
>
self
.
load_y
+
5
)
and
(
screen_x
>
self
.
load_x
+
18
)):
self
.
term_window
.
addnstr
(
self
.
load_y
,
self
.
load_x
,
"Load"
,
8
,
self
.
title_color
if
self
.
hascolors
else
curses
.
A_UNDERLINE
)
self
.
term_window
.
addnstr
(
self
.
load_y
,
self
.
load_x
+
10
,
"
%
"
,
8
)
self
.
term_window
.
addnstr
(
self
.
load_y
,
self
.
load_x
+
10
,
""
,
8
)
self
.
term_window
.
addnstr
(
self
.
load_y
+
1
,
self
.
load_x
,
"1 min:"
,
8
)
self
.
term_window
.
addnstr
(
self
.
load_y
+
2
,
self
.
load_x
,
"5 mins:"
,
8
)
self
.
term_window
.
addnstr
(
self
.
load_y
+
3
,
self
.
load_x
,
"15 mins:"
,
8
)
self
.
term_window
.
addnstr
(
self
.
load_y
+
1
,
self
.
load_x
+
10
,
str
(
load
[
'min1'
]),
8
,
self
.
__getColor
(
load
[
'min1'
])
)
self
.
term_window
.
addnstr
(
self
.
load_y
+
2
,
self
.
load_x
+
10
,
str
(
load
[
'min5'
]),
8
,
self
.
__getColor
(
load
[
'min5'
])
)
self
.
term_window
.
addnstr
(
self
.
load_y
+
3
,
self
.
load_x
+
10
,
str
(
load
[
'min15'
]),
8
,
self
.
__getColor
(
load
[
'min15'
])
)
self
.
term_window
.
addnstr
(
self
.
load_y
+
1
,
self
.
load_x
+
10
,
str
(
load
[
'min1'
]),
8
)
self
.
term_window
.
addnstr
(
self
.
load_y
+
2
,
self
.
load_x
+
10
,
str
(
load
[
'min5'
]),
8
)
self
.
term_window
.
addnstr
(
self
.
load_y
+
3
,
self
.
load_x
+
10
,
str
(
load
[
'min15'
]),
8
)
def
displayMem
(
self
,
mem
,
memswap
):
...
...
@@ -410,6 +496,10 @@ class glancesScreen():
def
displayNetwork
(
self
,
network
):
"""
Display the network interface bitrate
Return the number of interfaces
"""
# Network interfaces bitrate
screen_x
=
self
.
screen
.
getmaxyx
()[
1
]
screen_y
=
self
.
screen
.
getmaxyx
()[
0
]
...
...
@@ -417,32 +507,58 @@ class glancesScreen():
and
(
screen_x
>
self
.
network_x
+
28
)):
# Network interfaces bitrate
self
.
term_window
.
addnstr
(
self
.
network_y
,
self
.
network_x
,
"Net rate"
,
8
,
self
.
title_color
if
self
.
hascolors
else
curses
.
A_UNDERLINE
)
self
.
term_window
.
addnstr
(
self
.
network_y
,
self
.
network_x
+
10
,
"Rx
Kb
ps"
,
8
)
self
.
term_window
.
addnstr
(
self
.
network_y
,
self
.
network_x
+
20
,
"Tx
Kb
ps"
,
8
)
self
.
term_window
.
addnstr
(
self
.
network_y
,
self
.
network_x
+
10
,
"Rx
/
ps"
,
8
)
self
.
term_window
.
addnstr
(
self
.
network_y
,
self
.
network_x
+
20
,
"Tx
/
ps"
,
8
)
# Adapt the maximum interface to the screen
interface
=
0
for
interface
in
range
(
0
,
min
(
12
+
(
screen_y
-
self
.
term_h
),
len
(
network
))):
elapsed_time
=
max
(
1
,
network
[
interface
][
'systime'
])
self
.
term_window
.
addnstr
(
self
.
network_y
+
1
+
interface
,
self
.
network_x
,
network
[
interface
][
'interface_name'
]
+
':'
,
8
)
self
.
term_window
.
addnstr
(
self
.
network_y
+
1
+
interface
,
self
.
network_x
+
10
,
str
(
network
[
interface
][
'rx'
]
/
elapsed_time
/
1000
*
8
),
8
)
self
.
term_window
.
addnstr
(
self
.
network_y
+
1
+
interface
,
self
.
network_x
+
20
,
str
(
network
[
interface
][
'tx'
]
/
elapsed_time
/
1000
*
8
),
8
)
self
.
term_window
.
addnstr
(
self
.
network_y
+
1
+
interface
,
self
.
network_x
+
10
,
self
.
__autoUnit
(
network
[
interface
][
'rx'
]
/
elapsed_time
*
8
)
+
"b"
,
8
)
self
.
term_window
.
addnstr
(
self
.
network_y
+
1
+
interface
,
self
.
network_x
+
20
,
self
.
__autoUnit
(
network
[
interface
][
'tx'
]
/
elapsed_time
*
8
)
+
"b"
,
8
)
return
interface
return
0
def
displayDiskIO
(
self
,
diskio
):
def
displayDiskIO
(
self
,
diskio
,
offset_y
=
0
):
# Disk input/output rate
screen_x
=
self
.
screen
.
getmaxyx
()[
1
]
screen_y
=
self
.
screen
.
getmaxyx
()[
0
]
if
((
screen_y
>
self
.
diskio_y
+
4
)
self
.
diskio_y
=
offset_y
+
12
if
((
screen_y
>
self
.
diskio_y
+
3
)
and
(
screen_x
>
self
.
diskio_x
+
28
)):
self
.
term_window
.
addnstr
(
self
.
diskio_y
,
self
.
diskio_x
,
"Disk I/O"
,
8
,
self
.
title_color
if
self
.
hascolors
else
curses
.
A_UNDERLINE
)
self
.
term_window
.
addnstr
(
self
.
diskio_y
,
self
.
diskio_x
+
10
,
"In
KB
ps"
,
8
)
self
.
term_window
.
addnstr
(
self
.
diskio_y
,
self
.
diskio_x
+
20
,
"Out
KB
ps"
,
8
)
self
.
term_window
.
addnstr
(
self
.
diskio_y
,
self
.
diskio_x
+
10
,
"In
/
ps"
,
8
)
self
.
term_window
.
addnstr
(
self
.
diskio_y
,
self
.
diskio_x
+
20
,
"Out
/
ps"
,
8
)
# Adapt the maximum disk to the screen
for
disk
in
range
(
0
,
min
(
4
+
(
screen_y
-
self
.
term_h
),
len
(
diskio
))):
disk
=
0
for
disk
in
range
(
0
,
min
(
11
+
(
screen_y
-
self
.
term_h
),
len
(
diskio
))):
elapsed_time
=
max
(
1
,
diskio
[
disk
][
'systime'
])
self
.
term_window
.
addnstr
(
self
.
diskio_y
+
1
+
disk
,
self
.
diskio_x
,
diskio
[
disk
][
'disk_name'
]
+
':'
,
8
)
self
.
term_window
.
addnstr
(
self
.
diskio_y
+
1
+
disk
,
self
.
diskio_x
+
10
,
str
(
diskio
[
disk
][
'read_bytes'
]
/
elapsed_time
/
1000
),
8
)
self
.
term_window
.
addnstr
(
self
.
diskio_y
+
1
+
disk
,
self
.
diskio_x
+
20
,
str
(
diskio
[
disk
][
'write_bytes'
]
/
elapsed_time
/
1000
),
8
)
self
.
term_window
.
addnstr
(
self
.
diskio_y
+
1
+
disk
,
self
.
diskio_x
+
10
,
self
.
__autoUnit
(
diskio
[
disk
][
'write_bytes'
]
/
elapsed_time
)
+
"B"
,
8
)
self
.
term_window
.
addnstr
(
self
.
diskio_y
+
1
+
disk
,
self
.
diskio_x
+
20
,
self
.
__autoUnit
(
diskio
[
disk
][
'read_bytes'
]
/
elapsed_time
)
+
"B"
,
8
)
return
disk
return
0
def
displayFs
(
self
,
fs
,
offset_y
=
0
):
# Filesystem stats
screen_x
=
self
.
screen
.
getmaxyx
()[
1
]
screen_y
=
self
.
screen
.
getmaxyx
()[
0
]
self
.
fs_y
=
offset_y
+
15
if
((
screen_y
>
self
.
fs_y
+
5
)
and
(
screen_x
>
self
.
fs_x
+
28
)):
self
.
term_window
.
addnstr
(
self
.
fs_y
,
self
.
fs_x
,
"Mount"
,
8
,
self
.
title_color
if
self
.
hascolors
else
curses
.
A_UNDERLINE
)
self
.
term_window
.
addnstr
(
self
.
fs_y
,
self
.
fs_x
+
10
,
"Total"
,
8
)
self
.
term_window
.
addnstr
(
self
.
fs_y
,
self
.
fs_x
+
20
,
"Used"
,
8
)
# Adapt the maximum disk to the screen
mounted
=
0
for
mounted
in
range
(
0
,
min
(
11
+
(
screen_y
-
self
.
term_h
),
len
(
fs
))):
self
.
term_window
.
addnstr
(
self
.
fs_y
+
1
+
mounted
,
self
.
fs_x
,
fs
[
mounted
][
'mnt_point'
],
8
)
self
.
term_window
.
addnstr
(
self
.
fs_y
+
1
+
mounted
,
self
.
fs_x
+
10
,
self
.
__autoUnit
(
fs
[
mounted
][
'size'
]),
8
)
self
.
term_window
.
addnstr
(
self
.
fs_y
+
1
+
mounted
,
self
.
fs_x
+
20
,
self
.
__autoUnit
(
fs
[
mounted
][
'used'
]),
8
,
self
.
__getColor
(
fs
[
mounted
][
'used'
],
fs
[
mounted
][
'size'
]))
return
mounted
return
0
def
displayProcess
(
self
,
processcount
,
processlist
):
# Process
...
...
@@ -480,7 +596,7 @@ class glancesScreen():
self
.
term_window
.
addnstr
(
self
.
process_y
+
4
+
processes
,
self
.
process_x
,
"%.1f"
%
processlist
[
processes
][
'cpu_percent'
],
8
,
self
.
__getColor
(
processlist
[
processes
][
'cpu_percent'
]))
self
.
term_window
.
addnstr
(
self
.
process_y
+
4
+
processes
,
self
.
process_x
+
10
,
str
((
processlist
[
processes
][
'proc_size'
])
/
1048576
),
8
)
self
.
term_window
.
addnstr
(
self
.
process_y
+
4
+
processes
,
self
.
process_x
+
20
,
str
((
processlist
[
processes
][
'proc_resident'
])
/
1048576
),
8
)
self
.
term_window
.
addnstr
(
self
.
process_y
+
4
+
processes
,
self
.
process_x
+
30
,
processlist
[
processes
][
'process_name'
],
20
)
self
.
term_window
.
addnstr
(
self
.
process_y
+
4
+
processes
,
self
.
process_x
+
30
,
processlist
[
processes
][
'process_name'
],
20
+
(
screen_x
-
self
.
process_x
)
)
def
displayCaption
(
self
):
...
...
@@ -501,7 +617,7 @@ class glancesScreen():
screen_y
=
self
.
screen
.
getmaxyx
()[
0
]
if
((
screen_y
>
self
.
now_y
)
and
(
screen_x
>
self
.
now_x
)):
now_msg
=
now
.
strftime
(
"%Y-%m-%d %H:%M:%S"
)
+
" "
+
str
(
screen_y
)
now_msg
=
now
.
strftime
(
"%Y-%m-%d %H:%M:%S"
)
self
.
term_window
.
addnstr
(
max
(
self
.
now_y
,
screen_y
-
1
),
self
.
now_x
-
len
(
now_msg
),
now_msg
,
len
(
now_msg
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录