#iotop是一个python编写的命令行下图形展示磁盘占用率的工具,学习python,看看他的源码,记录一下

#主程序文件 iotop


#__future__ 可调用新版本的一些模块使用
from __future__ import print_function
#导入系统模块
import sys


#try..except..else用法
#try..except语句来处理异常。我们把通常的语句放在try-块中,而把我们的错误处理语句放在except-块中,执行完try后,执行else中的try语句。
try:
        #导入了main函数
    from iotop.ui import main
except ImportError as e:
    print(e)
    print('To run an uninstalled copy of iotop,')
    print('launch iotop.py in the top directory')
else:
    try:
    #执行main函数
        main()
    except KeyboardInterrupt:
        pass
    sys.exit(0)
    
#分析ui模块里的main,如下
#定义了用法的变量

USAGE = '''%s [OPTIONS]

DISK READ and DISK WRITE are the block I/O bandwidth used during the sampling
period. SWAPIN and IO are the percentages of time the thread spent respectively
while swapping in and waiting on I/O more generally. PRIO is the I/O priority at
which the thread is running (set using the ionice command).

Controls: left and right arrows to change the sorting column, r to invert the
sorting order, o to toggle the --only option, p to toggle the --processes
option, a to toggle the --accumulated option, i to change I/O priority, q to
quit, any other key to force a refresh.''' % sys.argv[0]


#main函数
def main():
    try:
            #设置语系
        locale.setlocale(locale.LC_ALL, '')
    except locale.Error:
        print('unable to set locale, falling back to the default locale')
    #optparse 命令行模块
    #action的方法有store_true append 
    #add_option添加命令行参数
    parser = optparse.OptionParser(usage=USAGE, version='iotop ' + VERSION)
    parser.add_option('-o', '--only', action='store_true',
                      dest='only', default=False,
                      help='only show processes or threads actually doing I/O')
    parser.add_option('-b', '--batch', action='store_true', dest='batch',
                      help='non-interactive mode')
    parser.add_option('-n', '--iter', type='int', dest='iterations',
                      metavar='NUM',
                      help='number of iterations before ending [infinite]')
    parser.add_option('-d', '--delay', type='float', dest='delay_seconds',
                      help='delay between iterations [1 second]',
                      metavar='SEC', default=1)
    parser.add_option('-p', '--pid', type='int', dest='pids', action='append',
                      help='processes/threads to monitor [all]', metavar='PID')
    parser.add_option('-u', '--user', type='str', dest='users', action='append',
                      help='users to monitor [all]', metavar='USER')
    parser.add_option('-P', '--processes', action='store_true',
                      dest='processes', default=False,
                      help='only show processes, not all threads')
    parser.add_option('-a', '--accumulated', action='store_true',
                      dest='accumulated', default=False,
                      help='show accumulated I/O instead of bandwidth')
    parser.add_option('-k', '--kilobytes', action='store_true',
                      dest='kilobytes', default=False,
                      help='use kilobytes instead of a human friendly unit')
    parser.add_option('-t', '--time', action='store_true', dest='time',
                      help='add a timestamp on each line (implies --batch)')
    parser.add_option('-q', '--quiet', action='count', dest='quiet', default=0,
                      help='suppress some lines of header (implies --batch)')
    parser.add_option('--profile', action='store_true', dest='profile',
                      default=False, help=optparse.SUPPRESS_HELP)
                    
                    
        #调用 parse_args() 来解析程序的命令行
    options, args = parser.parse_args()
    if args:
        parser.error('Unexpected arguments: ' + ' '.join(args))
     
    #find_uids,判断用户的UID函数
    find_uids(options)
    ####################################################################
    #根据获得用户的值,获取UID

    def find_uids(options):
    """Build options.uids from options.users by resolving usernames to UIDs"""
    #定义一个序列
    options.uids = []
    error = False
    for u in options.users or []:
        try:
            uid = int(u)
        except ValueError:
            try:
                #
                passwd = pwd.getpwnam(u)
            except KeyError:
                print('Unknown user:', u, file=sys.stderr)
                error = True
            else:
                uid = passwd.pw_uid
        if not error:
            #把uid加入到序列里
            options.uids.append(uid)
    if error:
        sys.exit(1)    
    ####################################################################
    options.pids = options.pids or []
    options.batch = options.batch or options.time or options.quiet

    main_loop = lambda: run_iotop(options)

    if options.profile:
        def safe_main_loop():
            try:
                main_loop()
            except:
                pass
        _profile(safe_main_loop)
    else:
        main_loop()