From 15f8a12a02ffef366c65962de93fe446707b25f8 Mon Sep 17 00:00:00 2001 From: Alexey Avramov Date: Wed, 30 Jan 2019 03:05:08 +0900 Subject: [PATCH] fix oom-sort: fix UnucideDecodeError and fix PID len --- README.md | 7 +- nohang | 10 +- oom-sort | 394 ++++++++++++++++++++++++----------------------- oom-sort.old | 222 ++++++++++++++++++++++++++ oom-sort.old.old | 122 +++++++++++++++ os04 | 277 +++++++++++++++++++++++++++++++++ os05 | 326 +++++++++++++++++++++++++++++++++++++++ os06 | 239 ++++++++++++++++++++++++++++ os07 | 220 ++++++++++++++++++++++++++ os08 | 222 ++++++++++++++++++++++++++ 10 files changed, 1841 insertions(+), 198 deletions(-) create mode 100755 oom-sort.old create mode 100755 oom-sort.old.old create mode 100755 os04 create mode 100755 os05 create mode 100755 os06 create mode 100755 os07 create mode 100755 os08 diff --git a/README.md b/README.md index 37361ae..2321fc3 100644 --- a/README.md +++ b/README.md @@ -87,8 +87,13 @@ To uninstall: $ sudo make uninstall ``` -For Arch Linux, there's an [AUR package](https://aur.archlinux.org/packages/nohang-git/). Use your favorite [AUR helper](https://wiki.archlinux.org/index.php/AUR_helpers). +For Arch Linux, there's an [AUR package](https://aur.archlinux.org/packages/nohang-git/). Use your favorite [AUR helper](https://wiki.archlinux.org/index.php/AUR_helpers). For example, +```bash +$ yay -S nohang-git +$ sudo systemctl start nohang +$ sudo systemctl enable nohang +``` ## How to configure nohang diff --git a/nohang b/nohang index 75381c4..b512609 100755 --- a/nohang +++ b/nohang @@ -22,8 +22,10 @@ else: wait_time = 12 +# todo: make config option max_sleep_time = 2 +# todo: make config option min_sleep_time = 0.1 notify_helper_path = '/usr/sbin/nohang_notify_helper' @@ -34,12 +36,12 @@ psi_support = os.path.exists(psi_path) HR = '~' * 79 +# todo: make config option print_total_stat = True ########################################################################## - -# function definition section +# define functions def update_stat_dict_and_print(key): @@ -848,8 +850,8 @@ def calculate_percent(arg_key): # find mem_total # find positions of SwapFree and SwapTotal in /proc/meminfo -with open('/proc/meminfo') as file: - mem_list = file.readlines() +with open('/proc/meminfo') as f: + mem_list = f.readlines() mem_list_names = [] for s in mem_list: diff --git a/oom-sort b/oom-sort index 71a1939..53633b4 100755 --- a/oom-sort +++ b/oom-sort @@ -3,220 +3,228 @@ sort processes by oom_score """ -# @TODO: user input validation - +from operator import itemgetter from os import listdir from argparse import ArgumentParser -from time import sleep -def parse_arguments(): - """ - parse CLI args - """ - parser = ArgumentParser() - parser.add_argument( - '--num', - '-n', - help="""max number of lines; default: 99999""", - default=99999, - type=int - ) - parser.add_argument( - '--len', - '-l', - help="""max cmdline length; default: 99999""", - default=99999, - type=int - ) - parser.add_argument( - '--refresh', - '-r', - help='refresh interval (0 to disable); default: 0. ' - 'Use it with --num/-n to also limit the output length', - default=0, - type=int - ) - return parser.parse_args() +"""#######################################################################79""" -def human_readable(num): +# define funtcions + + +def pid_to_oom_score(pid): + with open('/proc/' + pid + '/oom_score') as f: + return f.readline()[:-1] + + +def pid_to_oom_score_adj(pid): + with open('/proc/' + pid + '/oom_score_adj') as f: + return f.readline()[:-1] + + +def pid_to_cmdline(pid): """ - KiB to MiB + Get process cmdline by pid. + + pid: str pid of required process + returns string cmdline """ + with open('/proc/' + pid + '/cmdline') as f: + return f.read().replace('\x00', ' ').rstrip() + + +def pid_to_status_units(pid): + + with open('/proc/' + pid + '/status', 'rb') as f: + f_list = f.read().decode('utf-8', 'ignore').split('\n') + + for i in range(len(f_list)): + + if i is 1: + name = f_list[0].split('\t')[1] + + if i is uid_index: + uid = f_list[i].split('\t')[2] + + if i is vm_rss_index: + vm_rss = f_list[i].split('\t')[1][:-3] + + if i is vm_swap_index: + vm_swap = f_list[i].split('\t')[1][:-3] + + return name, uid, vm_rss, vm_swap + + +def get_max_pid_len(): + with open('/proc/sys/kernel/pid_max') as file: + for line in file: + return len(line.strip()) + + +''' +def get_max_vm_rss_len(): + with open('/proc/meminfo') as file: + kib = file.readline()[:-4].split(':')[1].lstrip() + return len(str(round(float(kib) / 1024))) +''' + + +def human(num): + '''Convert KiB to MiB and right align''' return str(round(num / 1024.0)).rjust(6, ' ') -def clear_screen(): - """ - print ANSI sequence to clear the screen - """ - print('\033c') +"""#######################################################################79""" -class TableIndexes: # pylint: disable=too-few-public-methods - """ - table headers from /proc/*/status for further - searching positions of VmRSS and VmSwap in each process output - """ +# parse input - def __init__(self): - with open('/proc/self/status') as status_file: - status_list = status_file.readlines() - - status_names = [] - for line in status_list: - status_names.append(line.split(':')[0]) - - self.vm_rss = status_names.index('VmRSS') - self.vm_swap = status_names.index('VmSwap') - self.uid = status_names.index('Uid') +# todo: input validation -INDEX = TableIndexes() +parser = ArgumentParser() + +parser.add_argument( + '--num', + '-n', + help="""max number of lines; default: 99999""", + default=None, + type=str +) + +parser.add_argument( + '--len', + '-l', + help="""max cmdline length; default: 99999""", + default=None, + type=str +) + +args = parser.parse_args() + +display_cmdline = args.len +num_lines = args.num +if num_lines is None: + num_lines = 99999 + +if display_cmdline is None: + display_cmdline = 99999 -class ProcessInfo: +"""#######################################################################79""" - pid = None - cmdline = None - oom_score = None - oom_score_adj = None +# find VmRSS, VmSwap and UID positions in /proc/*/status - name = None - uid = None - vm_rss = None - vm_swap = None +with open('/proc/self/status') as file: + status_list = file.readlines() - @classmethod - def from_pid(cls, pid): - """ - create ProcessInfo instance reading process info from /proc/{pid}/ - """ - info = cls() - info.pid = pid - try: - with open('/proc/' + pid + '/cmdline') as file: - try: - info.cmdline = file.readlines()[0].replace('\x00', ' ') - except IndexError: - return None - with open('/proc/' + pid + '/oom_score') as file: - info.oom_score = int(file.readlines()[0][:-1]) - with open('/proc/' + pid + '/oom_score_adj') as file: - info.oom_score_adj = int(file.readlines()[0][:-1]) - except FileNotFoundError: - return None - except ProcessLookupError: - return None - return info +# список имен из /proc/*/status для дальнейшего поиска позиций VmRSS and VmSwap +status_names = [] +for s in status_list: + status_names.append(s.split(':')[0]) - def read_status(self): - """ - return True if process have info in /proc/{pid}/status - """ - try: - # @TODO: stop reading file after VmSwap value retrieved - with open('/proc/' + self.pid + '/status') as file: - status_list = file.readlines() - self.vm_rss = int( - status_list[INDEX.vm_rss].split(':')[1].split(' ')[-2] - ) - self.vm_swap = int( - status_list[INDEX.vm_swap].split(':')[1].split(' ')[-2] - ) - self.name = status_list[0][:-1].split('\t')[1] - self.uid = status_list[INDEX.uid].split('\t')[1] - except FileNotFoundError: - return False - except ProcessLookupError: - return False - return True +vm_rss_index = status_names.index('VmRSS') +vm_swap_index = status_names.index('VmSwap') +uid_index = status_names.index('Uid') - def format_output(self, display_cmdline): - """ - format output for printing - """ - return '{} {} {} {} {} {} M {} M {}'.format( - str(self.oom_score).rjust(9), - str(self.oom_score_adj).rjust(13), - self.uid.rjust(5), - str(self.pid).rjust(5), - self.name.ljust(15), - human_readable(self.vm_rss), - human_readable(self.vm_swap), - self.cmdline[:display_cmdline] + +"""#######################################################################79""" + +# get sorted list with pid, oom_score, oom_score_adj, cmdline +# get status units: name, uid, rss, swap + + +oom_list = [] + +for pid in listdir('/proc'): + + # пропускаем элементы, состоящие не из цифр и PID 1 + if pid.isdigit() is False or pid == '1': + continue + + try: + + oom_score = pid_to_oom_score(pid) + + oom_score_adj = pid_to_oom_score_adj(pid) + + cmdline = pid_to_cmdline(pid) + if cmdline == '': + continue + + name, uid, vm_rss, vm_swap = pid_to_status_units(pid) + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + oom_list.append(( + int(pid), int(oom_score), int(oom_score_adj), cmdline, name, int(uid), int(vm_rss), int(vm_swap))) + +# list sorted by oom_score +oom_list_sorted = sorted(oom_list, key=itemgetter(1), reverse=True) + + +''' +max_uid_len = len(str(sorted( + oom_list, key=itemgetter(5), reverse=True)[0][5])) + + +max_vm_rss_len = len(str(round( + sorted(oom_list, key=itemgetter(6), reverse=True)[0][6] / 1024.0))) +''' + + +"""#######################################################################79""" + + +# print table + + +max_pid_len = get_max_pid_len() + +if display_cmdline == '0': + + print( + 'oom_score oom_score_adj UID{}PID Name ' + 'VmRSS VmSwap'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- --------'.format('-' * max_pid_len)) + +else: + + print('oom_score oom_score_adj UID{}PID Name ' + ' VmRSS VmSwap cmdline'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- -------- -------'.format('-' * max_pid_len)) + + +for i in oom_list_sorted[:int(num_lines)]: + + pid = i[0] + oom_score = i[1] + oom_score_adj = i[2] + cmdline = i[3] + name = i[4] + uid = i[5] + vm_rss = i[6] + vm_swap = i[7] + + print( + '{} {} {} {} {} {} M {} M {}'.format( + str(oom_score).rjust(9), + str(oom_score_adj).rjust(13), + str(uid).rjust(5), + str(pid).rjust(max_pid_len), + name.ljust(15), + human(vm_rss), + human(vm_swap), + cmdline[:int(display_cmdline)] ) - - -class Application: - """ - oom-sort application - """ - - oom_list = None - - def __init__(self): - args = parse_arguments() - self.num_lines = args.num - self.display_cmdline = args.len - self.refresh_interval = args.refresh - - def print_stats(self): - """ - print processes stats sorted by OOM score - """ - - oom_list = [] - for pid in listdir('/proc'): - # skip non-numeric entries and PID 1 - if pid.isdigit() is not True or pid == '1': - continue - proc_info = ProcessInfo.from_pid(pid) - if proc_info: - oom_list.append(proc_info) - oom_list.sort(key=lambda p: p.oom_score, reverse=True) - - if self.display_cmdline == 0: - print('oom_score oom_score_adj UID PID Name VmRSS VmSwap') - print('--------- ------------- ----- ----- --------------- -------- --------') - else: - print('oom_score oom_score_adj UID PID Name VmRSS VmSwap cmdline') - print('--------- ------------- ----- ----- --------------- -------- -------- -------') - - # iterate through list sorted by oom_score and print name, pid, etc - for proc_info in oom_list[:self.num_lines]: - if proc_info.read_status(): - print( - proc_info.format_output( - display_cmdline=self.display_cmdline - ) - ) - - def oom_top(self): - """ - show `top`-like refreshing stats - """ - while True: - try: - clear_screen() - print("Refreshing each {} seconds, press to interrupt:".format( - self.refresh_interval - )) - self.print_stats() - sleep(self.refresh_interval) - except KeyboardInterrupt: - break - - def main(self): - """ - application entrypoint - """ - if not self.refresh_interval: - self.print_stats() - else: - self.oom_top() - - -if __name__ == "__main__": - Application().main() + ) diff --git a/oom-sort.old b/oom-sort.old new file mode 100755 index 0000000..71a1939 --- /dev/null +++ b/oom-sort.old @@ -0,0 +1,222 @@ +#!/usr/bin/env python3 +""" +sort processes by oom_score +""" + +# @TODO: user input validation + +from os import listdir +from argparse import ArgumentParser +from time import sleep + + +def parse_arguments(): + """ + parse CLI args + """ + parser = ArgumentParser() + parser.add_argument( + '--num', + '-n', + help="""max number of lines; default: 99999""", + default=99999, + type=int + ) + parser.add_argument( + '--len', + '-l', + help="""max cmdline length; default: 99999""", + default=99999, + type=int + ) + parser.add_argument( + '--refresh', + '-r', + help='refresh interval (0 to disable); default: 0. ' + 'Use it with --num/-n to also limit the output length', + default=0, + type=int + ) + return parser.parse_args() + + +def human_readable(num): + """ + KiB to MiB + """ + return str(round(num / 1024.0)).rjust(6, ' ') + + +def clear_screen(): + """ + print ANSI sequence to clear the screen + """ + print('\033c') + + +class TableIndexes: # pylint: disable=too-few-public-methods + """ + table headers from /proc/*/status for further + searching positions of VmRSS and VmSwap in each process output + """ + + def __init__(self): + with open('/proc/self/status') as status_file: + status_list = status_file.readlines() + + status_names = [] + for line in status_list: + status_names.append(line.split(':')[0]) + + self.vm_rss = status_names.index('VmRSS') + self.vm_swap = status_names.index('VmSwap') + self.uid = status_names.index('Uid') + + +INDEX = TableIndexes() + + +class ProcessInfo: + + pid = None + cmdline = None + oom_score = None + oom_score_adj = None + + name = None + uid = None + vm_rss = None + vm_swap = None + + @classmethod + def from_pid(cls, pid): + """ + create ProcessInfo instance reading process info from /proc/{pid}/ + """ + info = cls() + info.pid = pid + try: + with open('/proc/' + pid + '/cmdline') as file: + try: + info.cmdline = file.readlines()[0].replace('\x00', ' ') + except IndexError: + return None + with open('/proc/' + pid + '/oom_score') as file: + info.oom_score = int(file.readlines()[0][:-1]) + with open('/proc/' + pid + '/oom_score_adj') as file: + info.oom_score_adj = int(file.readlines()[0][:-1]) + except FileNotFoundError: + return None + except ProcessLookupError: + return None + return info + + def read_status(self): + """ + return True if process have info in /proc/{pid}/status + """ + try: + # @TODO: stop reading file after VmSwap value retrieved + with open('/proc/' + self.pid + '/status') as file: + status_list = file.readlines() + self.vm_rss = int( + status_list[INDEX.vm_rss].split(':')[1].split(' ')[-2] + ) + self.vm_swap = int( + status_list[INDEX.vm_swap].split(':')[1].split(' ')[-2] + ) + self.name = status_list[0][:-1].split('\t')[1] + self.uid = status_list[INDEX.uid].split('\t')[1] + except FileNotFoundError: + return False + except ProcessLookupError: + return False + return True + + def format_output(self, display_cmdline): + """ + format output for printing + """ + return '{} {} {} {} {} {} M {} M {}'.format( + str(self.oom_score).rjust(9), + str(self.oom_score_adj).rjust(13), + self.uid.rjust(5), + str(self.pid).rjust(5), + self.name.ljust(15), + human_readable(self.vm_rss), + human_readable(self.vm_swap), + self.cmdline[:display_cmdline] + ) + + +class Application: + """ + oom-sort application + """ + + oom_list = None + + def __init__(self): + args = parse_arguments() + self.num_lines = args.num + self.display_cmdline = args.len + self.refresh_interval = args.refresh + + def print_stats(self): + """ + print processes stats sorted by OOM score + """ + + oom_list = [] + for pid in listdir('/proc'): + # skip non-numeric entries and PID 1 + if pid.isdigit() is not True or pid == '1': + continue + proc_info = ProcessInfo.from_pid(pid) + if proc_info: + oom_list.append(proc_info) + oom_list.sort(key=lambda p: p.oom_score, reverse=True) + + if self.display_cmdline == 0: + print('oom_score oom_score_adj UID PID Name VmRSS VmSwap') + print('--------- ------------- ----- ----- --------------- -------- --------') + else: + print('oom_score oom_score_adj UID PID Name VmRSS VmSwap cmdline') + print('--------- ------------- ----- ----- --------------- -------- -------- -------') + + # iterate through list sorted by oom_score and print name, pid, etc + for proc_info in oom_list[:self.num_lines]: + if proc_info.read_status(): + print( + proc_info.format_output( + display_cmdline=self.display_cmdline + ) + ) + + def oom_top(self): + """ + show `top`-like refreshing stats + """ + while True: + try: + clear_screen() + print("Refreshing each {} seconds, press to interrupt:".format( + self.refresh_interval + )) + self.print_stats() + sleep(self.refresh_interval) + except KeyboardInterrupt: + break + + def main(self): + """ + application entrypoint + """ + if not self.refresh_interval: + self.print_stats() + else: + self.oom_top() + + +if __name__ == "__main__": + Application().main() diff --git a/oom-sort.old.old b/oom-sort.old.old new file mode 100755 index 0000000..1b9e5f8 --- /dev/null +++ b/oom-sort.old.old @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 +""" +sort processes by oom_score +""" + +# нужна еще валидация cli ввода + +from operator import itemgetter +from os import listdir +from argparse import ArgumentParser + +parser = ArgumentParser() + +parser.add_argument( + '--num', + '-n', + help="""max number of lines; default: 99999""", + default=None, + type=str +) + +parser.add_argument( + '--len', + '-l', + help="""max cmdline length; default: 99999""", + default=None, + type=str +) + +args = parser.parse_args() + +display_cmdline = args.len +num_lines = args.num +if num_lines == None: + num_lines = 99999 + +if display_cmdline == None: + display_cmdline = 99999 + +def human(num): + '''KiB to MiB''' + return str(round(num / 1024.0)).rjust(6, ' ') + +with open('/proc/self/status') as file: + status_list = file.readlines() + +# список имен из /proc/*/status для дальнейшего поиска позиций VmRSS and VmSwap +status_names = [] +for s in status_list: + status_names.append(s.split(':')[0]) + +vm_rss_index = status_names.index('VmRSS') +vm_swap_index = status_names.index('VmSwap') +uid_index = status_names.index('Uid') + +oom_list = [] +for pid in listdir('/proc'): + # пропускаем элементы, состоящие не из цифр и PID 1 + if pid.isdigit() is not True or pid == '1': + continue + try: + with open('/proc/' + pid + '/cmdline') as file: + try: + cmdline = file.readlines()[0].replace('\x00', ' ') + except IndexError: + continue + with open('/proc/' + pid + '/oom_score') as file: + oom_score = int(file.readlines()[0][:-1]) + with open('/proc/' + pid + '/oom_score_adj') as file: + oom_score_adj = int(file.readlines()[0][:-1]) + except FileNotFoundError: + continue + except ProcessLookupError: + continue + + oom_list.append((pid, oom_score, oom_score_adj, cmdline)) + +# list sorted by oom_score +oom_list_sorted = sorted(oom_list, key=itemgetter(1), reverse=True) + +if display_cmdline == '0': + print('oom_score oom_score_adj UID PID Name VmRSS VmSwap') + print('--------- ------------- ----- ----- --------------- -------- --------') +else: + print('oom_score oom_score_adj UID PID Name VmRSS VmSwap cmdline') + print('--------- ------------- ----- ----- --------------- -------- -------- -------') + +# итерируемся по сортированному списку oom_score, печатая name, pid etc +for i in oom_list_sorted[:int(num_lines)]: + pid = i[0] + oom_score = i[1] + oom_score_adj = i[2] + cmdline = i[3].strip() + + try: + # читать часть файла не дальше VmSwap - когда-нибудь + with open('/proc/' + pid + '/status') as file: + status_list = file.readlines() + + vm_rss = int(status_list[vm_rss_index].split(':')[1].split(' ')[-2]) + vm_swap = int(status_list[vm_swap_index].split(':')[1].split(' ')[-2]) + name = status_list[0][:-1].split('\t')[1] + uid = status_list[uid_index].split('\t')[1] + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + print( + '{} {} {} {} {} {} M {} M {}'.format( + str(oom_score).rjust(9), + str(oom_score_adj).rjust(13), + uid.rjust(5), + str(pid).rjust(5), + name.ljust(15), + human(vm_rss), + human(vm_swap), + cmdline[:int(display_cmdline)] + ) + ) diff --git a/os04 b/os04 new file mode 100755 index 0000000..1cd659e --- /dev/null +++ b/os04 @@ -0,0 +1,277 @@ +#!/usr/bin/env python3 +""" +sort processes by oom_score +""" + +# REFACTORING IN PROGRESS + +from operator import itemgetter +from os import listdir +from argparse import ArgumentParser + + +"""#######################################################################79""" + +# define funtcions + + +def pid_to_cmdline(pid): + """ + Get process cmdline by pid. + + pid: str pid of required process + returns string cmdline + """ + with open('/proc/' + pid + '/cmdline') as f: + return f.read().replace('\x00', ' ').rstrip() + + +def pid_to_name(pid): + """ + Get process name by pid. + + pid: str pid of required process + returns string process_name + """ + try: + with open('/proc/' + pid + '/status') as f: + f.seek(6) + for line in f: + return line[:-1] + except FileNotFoundError: + return '' + except ProcessLookupError: + return '' + except UnicodeDecodeError: + with open('/proc/' + pid + '/status', 'rb') as f: + f.seek(6) + return f.read(15).decode( + 'utf-8', 'ignore').partition('\n')[0] + + + +def kib_to_mib(num): + """Convert KiB values to MiB values.""" + return round(num / 1024.0) + +def human(num): + '''KiB to MiB''' + return str(round(num / 1024.0)).rjust(6, ' ') + + +def get_max_pid_len(): + with open('/proc/sys/kernel/pid_max') as file: + for line in file: + return len(line.strip()) + + +def get_max_vm_rss_len(): + pass + + + +def pid_to_status_units(pid): + + with open('/proc/' + pid + '/status', 'rb') as f: + f_list = f.read().decode('utf-8', 'ignore').split('\n') + + for i in range(len(f_list)): + + if i is 1: + name = f_list[0].split('\t')[1] + print(i, 'Name:', name) + + if i is uid_index: + uid = f_list[i].split('\t')[2] + print(i, 'UID:', uid) + + if i is vm_rss_index: + pass + vm_rss = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + print(i, 'rss:', vm_rss) + + if i is vm_swap_index: + pass + vm_swap = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + print(i, 'swap:', vm_swap) + + + + +"""#######################################################################79""" + + +# parse input + +# todo: input validation + + +parser = ArgumentParser() + +parser.add_argument( + '--num', + '-n', + help="""max number of lines; default: 99999""", + default=None, + type=str +) + +parser.add_argument( + '--len', + '-l', + help="""max cmdline length; default: 99999""", + default=None, + type=str +) + +args = parser.parse_args() + +display_cmdline = args.len +num_lines = args.num +if num_lines is None: + num_lines = 20 + +if display_cmdline is None: + display_cmdline = 20 + + +"""#######################################################################79""" + +# find VmRSS, VmSwap and UID positions in /proc/*/status + +with open('/proc/self/status') as file: + status_list = file.readlines() + +# список имен из /proc/*/status для дальнейшего поиска позиций VmRSS and VmSwap +status_names = [] +for s in status_list: + status_names.append(s.split(':')[0]) + +vm_rss_index = status_names.index('VmRSS') +vm_swap_index = status_names.index('VmSwap') +uid_index = status_names.index('Uid') + + + + + + + + + + + + + + + +"""#######################################################################79""" + +# get sorted list with pid, oom_score, oom_score_adj, cmdline + +# здесь же искать вообще все. + + +oom_list = [] + +for pid in listdir('/proc'): + + # пропускаем элементы, состоящие не из цифр и PID 1 + if pid.isdigit() is False or pid == '1': + continue + + + ''' + + + name = pid_to_name(pid) + ''' + + try: + cmdline = pid_to_cmdline(pid) + if cmdline == '': + continue + + with open('/proc/' + pid + '/oom_score') as file: + oom_score = int(file.readlines()[0][:-1]) + + with open('/proc/' + pid + '/oom_score_adj') as file: + oom_score_adj = int(file.readlines()[0][:-1]) + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + oom_list.append((pid, oom_score, oom_score_adj, cmdline)) + +# list sorted by oom_score +oom_list_sorted = sorted(oom_list, key=itemgetter(1), reverse=True) + + + + + +"""#######################################################################79""" + + +# print table + + +max_pid_len = get_max_pid_len() + +if display_cmdline == '0': + + print( + 'oom_score oom_score_adj UID{}PID Name VmRSS VmSwap'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- --------'.format('-' * max_pid_len)) + +else: + + print('oom_score oom_score_adj UID{}PID Name ' + ' VmRSS VmSwap cmdline'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- -------- -------'.format('-' * max_pid_len)) + +# итерируемся по сортированному списку oom_score, печатая name, pid etc + + +for i in oom_list_sorted[:int(num_lines)]: + + pid = i[0] + oom_score = i[1] + oom_score_adj = i[2] + cmdline = i[3] + + try: + # читать часть файла не дальше VmSwap - когда-нибудь + with open('/proc/' + pid + '/status') as file: + status_list = file.readlines() + + vm_rss = int(status_list[vm_rss_index].split(':')[1].split(' ')[-2]) + vm_swap = int(status_list[vm_swap_index].split(':')[1].split(' ')[-2]) + name = status_list[0][:-1].split('\t')[1] + uid = status_list[uid_index].split('\t')[1] + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + print( + '{} {} {} {} {} {} M {} M {}'.format( + str(oom_score).rjust(9), + str(oom_score_adj).rjust(13), + uid.rjust(5), + str(pid).rjust(max_pid_len), + name.ljust(15), + human(vm_rss), + human(vm_swap), + cmdline[:int(display_cmdline)] + ) + ) diff --git a/os05 b/os05 new file mode 100755 index 0000000..2da9517 --- /dev/null +++ b/os05 @@ -0,0 +1,326 @@ +#!/usr/bin/env python3 +""" +sort processes by oom_score +""" + +# REFACTORING IN PROGRESS + +from operator import itemgetter +from os import listdir +from argparse import ArgumentParser + + +"""#######################################################################79""" + +# define funtcions + + +def pid_to_cmdline(pid): + """ + Get process cmdline by pid. + + pid: str pid of required process + returns string cmdline + """ + with open('/proc/' + pid + '/cmdline') as f: + return f.read().replace('\x00', ' ').rstrip() + + + +def pid_to_oom_score(pid): + with open('/proc/' + pid + '/oom_score') as f: + return f.readline()[:-1] + + +def pid_to_oom_score_adj(pid): + with open('/proc/' + pid + '/oom_score_adj') as f: + return f.readline()[:-1] + + + + + + + +def pid_to_status_units(pid): + + with open('/proc/' + pid + '/status', 'rb') as f: + f_list = f.read().decode('utf-8', 'ignore').split('\n') + + for i in range(len(f_list)): + + if i is 1: + name = f_list[0].split('\t')[1] + print(i, 'Name:', name) + + if i is uid_index: + uid = f_list[i].split('\t')[2] + print(i, 'UID:', uid) + + if i is vm_rss_index: + pass + vm_rss = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + print(i, 'rss:', vm_rss) + + if i is vm_swap_index: + pass + vm_swap = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + print(i, 'swap:', vm_swap) + + + +def get_max_pid_len(): + with open('/proc/sys/kernel/pid_max') as file: + for line in file: + return len(line.strip()) + + +def get_max_vm_rss_len(): + pass + + + + + + + + + + +def pid_to_name(pid): + """ + Get process name by pid. + + pid: str pid of required process + returns string process_name + """ + try: + with open('/proc/' + pid + '/status') as f: + f.seek(6) + for line in f: + return line[:-1] + except FileNotFoundError: + return '' + except ProcessLookupError: + return '' + except UnicodeDecodeError: + with open('/proc/' + pid + '/status', 'rb') as f: + f.seek(6) + return f.read(15).decode( + 'utf-8', 'ignore').partition('\n')[0] + + + +def kib_to_mib(num): + """Convert KiB values to MiB values.""" + return round(num / 1024.0) + +def human(num): + '''Convert KiB to MiB and right align, as you see''' + return str(round(num / 1024.0)).rjust(6, ' ') + + + + + + +def pid_to_status_units(pid): + + with open('/proc/' + pid + '/status', 'rb') as f: + f_list = f.read().decode('utf-8', 'ignore').split('\n') + + for i in range(len(f_list)): + + if i is 1: + name = f_list[0].split('\t')[1] + + if i is uid_index: + uid = f_list[i].split('\t')[2] + + if i is vm_rss_index: + vm_rss = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + + if i is vm_swap_index: + vm_swap = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + + return name, uid, vm_rss, vm_swap + + +"""#######################################################################79""" + + +# parse input + +# todo: input validation + + +parser = ArgumentParser() + +parser.add_argument( + '--num', + '-n', + help="""max number of lines; default: 99999""", + default=None, + type=str +) + +parser.add_argument( + '--len', + '-l', + help="""max cmdline length; default: 99999""", + default=None, + type=str +) + +args = parser.parse_args() + +display_cmdline = args.len +num_lines = args.num +if num_lines is None: + num_lines = 20 + +if display_cmdline is None: + display_cmdline = 20 + + +"""#######################################################################79""" + +# find VmRSS, VmSwap and UID positions in /proc/*/status + +with open('/proc/self/status') as file: + status_list = file.readlines() + +# список имен из /proc/*/status для дальнейшего поиска позиций VmRSS and VmSwap +status_names = [] +for s in status_list: + status_names.append(s.split(':')[0]) + +vm_rss_index = status_names.index('VmRSS') +vm_swap_index = status_names.index('VmSwap') +uid_index = status_names.index('Uid') + + + + + + + + + + + + + + + +"""#######################################################################79""" + +# get sorted list with pid, oom_score, oom_score_adj, cmdline +# get status units: name, uid, rss, swap + +# здесь же искать вообще все. + + +oom_list = [] + +for pid in listdir('/proc'): + + # пропускаем элементы, состоящие не из цифр и PID 1 + if pid.isdigit() is False or pid == '1': + continue + + + ''' + + + name = pid_to_name(pid) + ''' + + try: + cmdline = pid_to_cmdline(pid) + if cmdline == '': + continue + + with open('/proc/' + pid + '/oom_score') as file: + oom_score = int(file.readlines()[0][:-1]) + + with open('/proc/' + pid + '/oom_score_adj') as file: + oom_score_adj = int(file.readlines()[0][:-1]) + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + oom_list.append((pid, oom_score, oom_score_adj, cmdline)) + +# list sorted by oom_score +oom_list_sorted = sorted(oom_list, key=itemgetter(1), reverse=True) + + + + + +"""#######################################################################79""" + + +# print table + + +max_pid_len = get_max_pid_len() + +if display_cmdline == '0': + + print( + 'oom_score oom_score_adj UID{}PID Name VmRSS VmSwap'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- --------'.format('-' * max_pid_len)) + +else: + + print('oom_score oom_score_adj UID{}PID Name ' + ' VmRSS VmSwap cmdline'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- -------- -------'.format('-' * max_pid_len)) + +# итерируемся по сортированному списку oom_score, печатая name, pid etc + + +for i in oom_list_sorted[:int(num_lines)]: + + pid = i[0] + oom_score = i[1] + oom_score_adj = i[2] + cmdline = i[3] + + try: + # читать часть файла не дальше VmSwap - когда-нибудь + with open('/proc/' + pid + '/status') as file: + status_list = file.readlines() + + vm_rss = int(status_list[vm_rss_index].split(':')[1].split(' ')[-2]) + vm_swap = int(status_list[vm_swap_index].split(':')[1].split(' ')[-2]) + name = status_list[0][:-1].split('\t')[1] + uid = status_list[uid_index].split('\t')[1] + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + print( + '{} {} {} {} {} {} M {} M {}'.format( + str(oom_score).rjust(9), + str(oom_score_adj).rjust(13), + uid.rjust(5), + str(pid).rjust(max_pid_len), + name.ljust(15), + human(vm_rss), + human(vm_swap), + cmdline[:int(display_cmdline)] + ) + ) diff --git a/os06 b/os06 new file mode 100755 index 0000000..61753ad --- /dev/null +++ b/os06 @@ -0,0 +1,239 @@ +#!/usr/bin/env python3 +""" +sort processes by oom_score +""" + +# REFACTORING IN PROGRESS + +from operator import itemgetter +from os import listdir +from argparse import ArgumentParser + + +"""#######################################################################79""" + + +# define funtcions + + +def pid_to_oom_score(pid): + with open('/proc/' + pid + '/oom_score') as f: + return f.readline()[:-1] + + +def pid_to_oom_score_adj(pid): + with open('/proc/' + pid + '/oom_score_adj') as f: + return f.readline()[:-1] + + +def pid_to_cmdline(pid): + """ + Get process cmdline by pid. + + pid: str pid of required process + returns string cmdline + """ + with open('/proc/' + pid + '/cmdline') as f: + return f.read().replace('\x00', ' ').rstrip() + + +def pid_to_status_units(pid): + + with open('/proc/' + pid + '/status', 'rb') as f: + f_list = f.read().decode('utf-8', 'ignore').split('\n') + + for i in range(len(f_list)): + + if i is 1: + name = f_list[0].split('\t')[1] + + if i is uid_index: + uid = f_list[i].split('\t')[2] + + if i is vm_rss_index: + vm_rss = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + + if i is vm_swap_index: + vm_swap = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + + return name, uid, vm_rss, vm_swap + + +def get_max_pid_len(): + with open('/proc/sys/kernel/pid_max') as file: + for line in file: + return len(line.strip()) + + +def get_max_vm_rss_len(): + pass + + +def kib_to_mib(num): + """Convert KiB values to MiB values.""" + return round(num / 1024.0) + +def human(num): + '''Convert KiB to MiB and right align, as you see''' + return str(round(num / 1024.0)).rjust(6, ' ') + + +"""#######################################################################79""" + + +# parse input + +# todo: input validation + + +parser = ArgumentParser() + +parser.add_argument( + '--num', + '-n', + help="""max number of lines; default: 99999""", + default=None, + type=str +) + +parser.add_argument( + '--len', + '-l', + help="""max cmdline length; default: 99999""", + default=None, + type=str +) + +args = parser.parse_args() + +display_cmdline = args.len +num_lines = args.num +if num_lines is None: + num_lines = 20 + +if display_cmdline is None: + display_cmdline = 20 + + +"""#######################################################################79""" + +# find VmRSS, VmSwap and UID positions in /proc/*/status + +with open('/proc/self/status') as file: + status_list = file.readlines() + +# список имен из /proc/*/status для дальнейшего поиска позиций VmRSS and VmSwap +status_names = [] +for s in status_list: + status_names.append(s.split(':')[0]) + +vm_rss_index = status_names.index('VmRSS') +vm_swap_index = status_names.index('VmSwap') +uid_index = status_names.index('Uid') + + +"""#######################################################################79""" + +# get sorted list with pid, oom_score, oom_score_adj, cmdline +# get status units: name, uid, rss, swap + + +oom_list = [] + +for pid in listdir('/proc'): + + # пропускаем элементы, состоящие не из цифр и PID 1 + if pid.isdigit() is False or pid == '1': + continue + + try: + + oom_score = pid_to_oom_score(pid) + + oom_score_adj = pid_to_oom_score_adj(pid) + + cmdline = pid_to_cmdline(pid) + if cmdline == '': + continue + + name, uid, vm_rss, vm_swap = pid_to_status_units(pid) + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + oom_list.append((pid, oom_score, oom_score_adj, cmdline, name, uid, vm_rss, vm_swap)) + +# list sorted by oom_score +oom_list_sorted = sorted(oom_list, key=itemgetter(1), reverse=True) + + +"""#######################################################################79""" + + +# print table + + +max_pid_len = get_max_pid_len() + +if display_cmdline == '0': + + print( + 'oom_score oom_score_adj UID{}PID Name VmRSS VmSwap'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- --------'.format('-' * max_pid_len)) + +else: + + print('oom_score oom_score_adj UID{}PID Name ' + ' VmRSS VmSwap cmdline'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- -------- -------'.format('-' * max_pid_len)) + +# итерируемся по сортированному списку oom_score, печатая name, pid etc + + +for i in oom_list_sorted[:int(num_lines)]: + + pid = i[0] + oom_score = i[1] + oom_score_adj = i[2] + cmdline = i[3] + + + + + + + try: + # читать часть файла не дальше VmSwap - когда-нибудь + with open('/proc/' + pid + '/status') as file: + status_list = file.readlines() + + vm_rss = int(status_list[vm_rss_index].split(':')[1].split(' ')[-2]) + vm_swap = int(status_list[vm_swap_index].split(':')[1].split(' ')[-2]) + name = status_list[0][:-1].split('\t')[1] + uid = status_list[uid_index].split('\t')[1] + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + print( + '{} {} {} {} {} {} M {} M {}'.format( + str(oom_score).rjust(9), + str(oom_score_adj).rjust(13), + uid.rjust(5), + str(pid).rjust(max_pid_len), + name.ljust(15), + human(vm_rss), + human(vm_swap), + cmdline[:int(display_cmdline)] + ) + ) diff --git a/os07 b/os07 new file mode 100755 index 0000000..b9a6ca6 --- /dev/null +++ b/os07 @@ -0,0 +1,220 @@ +#!/usr/bin/env python3 +""" +sort processes by oom_score +""" + +from operator import itemgetter +from os import listdir +from argparse import ArgumentParser + + +"""#######################################################################79""" + + +# define funtcions + + +def pid_to_oom_score(pid): + with open('/proc/' + pid + '/oom_score') as f: + return f.readline()[:-1] + + +def pid_to_oom_score_adj(pid): + with open('/proc/' + pid + '/oom_score_adj') as f: + return f.readline()[:-1] + + +def pid_to_cmdline(pid): + """ + Get process cmdline by pid. + + pid: str pid of required process + returns string cmdline + """ + with open('/proc/' + pid + '/cmdline') as f: + return f.read().replace('\x00', ' ').rstrip() + + +def pid_to_status_units(pid): + + with open('/proc/' + pid + '/status', 'rb') as f: + f_list = f.read().decode('utf-8', 'ignore').split('\n') + + for i in range(len(f_list)): + + if i is 1: + name = f_list[0].split('\t')[1] + + if i is uid_index: + uid = f_list[i].split('\t')[2] + + if i is vm_rss_index: + vm_rss = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + + if i is vm_swap_index: + vm_swap = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + + return name, uid, vm_rss, vm_swap + + +def get_max_pid_len(): + with open('/proc/sys/kernel/pid_max') as file: + for line in file: + return len(line.strip()) + + +def get_max_vm_rss_len(): + pass + + +def kib_to_mib(num): + """Convert KiB values to MiB values.""" + return round(num / 1024.0) + +def human(num): + '''Convert KiB to MiB and right align, as you see''' + return str(round(num / 1024.0)).rjust(6, ' ') + + +"""#######################################################################79""" + + +# parse input + +# todo: input validation + + +parser = ArgumentParser() + +parser.add_argument( + '--num', + '-n', + help="""max number of lines; default: 99999""", + default=None, + type=str +) + +parser.add_argument( + '--len', + '-l', + help="""max cmdline length; default: 99999""", + default=None, + type=str +) + +args = parser.parse_args() + +display_cmdline = args.len +num_lines = args.num +if num_lines is None: + num_lines = 20 + +if display_cmdline is None: + display_cmdline = 20 + + +"""#######################################################################79""" + +# find VmRSS, VmSwap and UID positions in /proc/*/status + +with open('/proc/self/status') as file: + status_list = file.readlines() + +# список имен из /proc/*/status для дальнейшего поиска позиций VmRSS and VmSwap +status_names = [] +for s in status_list: + status_names.append(s.split(':')[0]) + +vm_rss_index = status_names.index('VmRSS') +vm_swap_index = status_names.index('VmSwap') +uid_index = status_names.index('Uid') + + +"""#######################################################################79""" + +# get sorted list with pid, oom_score, oom_score_adj, cmdline +# get status units: name, uid, rss, swap + + +oom_list = [] + +for pid in listdir('/proc'): + + # пропускаем элементы, состоящие не из цифр и PID 1 + if pid.isdigit() is False or pid == '1': + continue + + try: + + oom_score = pid_to_oom_score(pid) + + oom_score_adj = pid_to_oom_score_adj(pid) + + cmdline = pid_to_cmdline(pid) + if cmdline == '': + continue + + name, uid, vm_rss, vm_swap = pid_to_status_units(pid) + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + oom_list.append(( + pid, oom_score, oom_score_adj, cmdline, name, uid, vm_rss, vm_swap)) + +# list sorted by oom_score +oom_list_sorted = sorted(oom_list, key=itemgetter(1), reverse=True) + + +"""#######################################################################79""" + + +# print table + + +max_pid_len = get_max_pid_len() + +if display_cmdline == '0': + + print( + 'oom_score oom_score_adj UID{}PID Name ' \ + 'VmRSS VmSwap'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- --------'.format('-' * max_pid_len)) + +else: + + print('oom_score oom_score_adj UID{}PID Name ' + ' VmRSS VmSwap cmdline'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- -------- -------'.format('-' * max_pid_len)) + + +for i in oom_list_sorted[:int(num_lines)]: + + pid = i[0] + oom_score = i[1] + oom_score_adj = i[2] + cmdline = i[3] + name = i[4] + uid = i[5] + vm_rss = i[6] + vm_swap = i[7] + + print( + '{} {} {} {} {} {} M {} M {}'.format( + str(oom_score).rjust(9), + str(oom_score_adj).rjust(13), + uid.rjust(5), + str(pid).rjust(max_pid_len), + name.ljust(15), + human(vm_rss), + human(vm_swap), + cmdline[:int(display_cmdline)] + ) + ) diff --git a/os08 b/os08 new file mode 100755 index 0000000..af8a62b --- /dev/null +++ b/os08 @@ -0,0 +1,222 @@ +#!/usr/bin/env python3 +""" +sort processes by oom_score +""" + +from operator import itemgetter +from os import listdir +from argparse import ArgumentParser + + +"""#######################################################################79""" + + +# define funtcions + + +def pid_to_oom_score(pid): + with open('/proc/' + pid + '/oom_score') as f: + return f.readline()[:-1] + + +def pid_to_oom_score_adj(pid): + with open('/proc/' + pid + '/oom_score_adj') as f: + return f.readline()[:-1] + + +def pid_to_cmdline(pid): + """ + Get process cmdline by pid. + + pid: str pid of required process + returns string cmdline + """ + with open('/proc/' + pid + '/cmdline') as f: + return f.read().replace('\x00', ' ').rstrip() + + +def pid_to_status_units(pid): + + with open('/proc/' + pid + '/status', 'rb') as f: + f_list = f.read().decode('utf-8', 'ignore').split('\n') + + for i in range(len(f_list)): + + if i is 1: + name = f_list[0].split('\t')[1] + + if i is uid_index: + uid = f_list[i].split('\t')[2] + + if i is vm_rss_index: + vm_rss = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + + if i is vm_swap_index: + vm_swap = kib_to_mib(int(f_list[i].split('\t')[1][:-3])) + + return name, uid, vm_rss, vm_swap + + +def get_max_pid_len(): + with open('/proc/sys/kernel/pid_max') as file: + for line in file: + return len(line.strip()) + + +def get_max_vm_rss_len(): + pass + + +def kib_to_mib(num): + """Convert KiB values to MiB values.""" + return round(num / 1024.0) + + +def human(num): + '''Convert KiB to MiB and right align, as you see''' + return str(round(num / 1024.0)).rjust(6, ' ') + + +"""#######################################################################79""" + + +# parse input + +# todo: input validation + + +parser = ArgumentParser() + +parser.add_argument( + '--num', + '-n', + help="""max number of lines; default: 99999""", + default=None, + type=str +) + +parser.add_argument( + '--len', + '-l', + help="""max cmdline length; default: 99999""", + default=None, + type=str +) + +args = parser.parse_args() + +display_cmdline = args.len +num_lines = args.num +if num_lines is None: + num_lines = 99999 + +if display_cmdline is None: + display_cmdline = 99999 + + +"""#######################################################################79""" + +# find VmRSS, VmSwap and UID positions in /proc/*/status + +with open('/proc/self/status') as file: + status_list = file.readlines() + +# список имен из /proc/*/status для дальнейшего поиска позиций VmRSS and VmSwap +status_names = [] +for s in status_list: + status_names.append(s.split(':')[0]) + +vm_rss_index = status_names.index('VmRSS') +vm_swap_index = status_names.index('VmSwap') +uid_index = status_names.index('Uid') + + +"""#######################################################################79""" + +# get sorted list with pid, oom_score, oom_score_adj, cmdline +# get status units: name, uid, rss, swap + + +oom_list = [] + +for pid in listdir('/proc'): + + # пропускаем элементы, состоящие не из цифр и PID 1 + if pid.isdigit() is False or pid == '1': + continue + + try: + + oom_score = pid_to_oom_score(pid) + + oom_score_adj = pid_to_oom_score_adj(pid) + + cmdline = pid_to_cmdline(pid) + if cmdline == '': + continue + + name, uid, vm_rss, vm_swap = pid_to_status_units(pid) + + except FileNotFoundError: + continue + + except ProcessLookupError: + continue + + oom_list.append(( + pid, oom_score, oom_score_adj, cmdline, name, uid, vm_rss, vm_swap)) + +# list sorted by oom_score +oom_list_sorted = sorted(oom_list, key=itemgetter(1), reverse=True) + + +"""#######################################################################79""" + + +# print table +''' + +max_pid_len = get_max_pid_len() + +if display_cmdline == '0': + + print( + 'oom_score oom_score_adj UID{}PID Name ' \ + 'VmRSS VmSwap'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- --------'.format('-' * max_pid_len)) + +else: + + print('oom_score oom_score_adj UID{}PID Name ' + ' VmRSS VmSwap cmdline'.format(' ' * (max_pid_len - 2))) + + print('--------- ------------- ----- {} --------------- -' + '------- -------- -------'.format('-' * max_pid_len)) + + +for i in oom_list_sorted[:int(num_lines)]: + + pid = i[0] + oom_score = i[1] + oom_score_adj = i[2] + cmdline = i[3] + name = i[4] + uid = i[5] + vm_rss = i[6] + vm_swap = i[7] + + print( + '{} {} {} {} {} {} M {} M {}'.format( + str(oom_score).rjust(9), + str(oom_score_adj).rjust(13), + uid.rjust(5), + str(pid).rjust(max_pid_len), + name.ljust(15), + human(vm_rss), + human(vm_swap), + cmdline[:int(display_cmdline)] + ) + ) +'''