New upstream version 0.9.25
Dylan Aïssi
3 years ago
26 | 26 | - Bashtop version: |
27 | 27 | - (Linux) Linux distribution and version: |
28 | 28 | - (Linux) Data collection type (/proc or psutil): |
29 | - Psutil version: `python3 -c "import psutil; print(psutil.version_info)"` (version 5.7.0 or above is required): | |
29 | 30 | - (OSX/FreeBSD) Os release version: |
30 | 31 | - Terminal used: |
31 | 32 | - Font used: |
32 | - Bash version, "bash --version" (version 4.4 or above is required): | |
33 | - Locales: output of "locale -v" | |
33 | - Bash version, `bash --version` (version 4.4 or above is required): | |
34 | - Locales: output of `locale -v` | |
34 | 35 | |
35 | 36 | **Additional context** |
36 | 37 |
0 | 0 | # Changelog |
1 | ||
2 | ## v0.9.25 | |
3 | ||
4 | * Fixed: Crash when using "/proc" data collection and filesystem type is 9p, by @bolapara | |
5 | ||
6 | ## v0.9.24 | |
7 | ||
8 | * Fixed: Psutil script crash on OSX | |
9 | * Fixed: Error handling for malformed osx-cpu-temp output | |
10 | ||
11 | ## v0.9.23 | |
12 | ||
13 | * Fixed: kill/terminate/interrupt process not working in OsX and FreeBSD | |
1 | 14 | |
2 | 15 | ## v0.9.22 |
3 | 16 |
19 | 19 | * [Themes](#themes) |
20 | 20 | * [Upcoming](#upcoming) (Python port) |
21 | 21 | * [Support and funding](#support-and-funding) |
22 | * [Compatibility](#compatibility) (OSX and FreeBSD Support) | |
22 | * [Prerequisites](#prerequisites) | |
23 | 23 | * [Dependencies](#dependencies) |
24 | 24 | * [Screenshots](#screenshots) |
25 | 25 | * [Installation](#installation) |
66 | 66 | |
67 | 67 | ## Upcoming |
68 | 68 | |
69 | ~~Currently rewriting to use python3 [psutil](https://github.com/giampaolo/psutil) for data collection instead of linux specific tools. | |
70 | This will add python 3 and psutil as dependencies, but will make bashtop cross platform compatible.~~ | |
71 | ||
72 | ~~This will be integrated in to main version when done and add the possibility to switch between psutil and linux tools for users running linux.~~ | |
73 | ||
74 | Bashtop is now Mac OS X and FreeBSD compatible! | |
75 | ||
76 | 69 | #### Python port: bpytop |
77 | 70 | |
78 | 71 | Currently working full time on this during my vacation :) |
93 | 86 | |
94 | 87 | Any support is greatly appreciated! |
95 | 88 | |
96 | ## Compatibility | |
97 | ||
98 | Should work on most modern linux distributions, on Mac OS X and on FreeBSD. | |
99 | ||
100 | Will not display correctly on the standard terminal on OSX! | |
89 | ## Prerequisites | |
90 | ||
91 | #### Mac Os X | |
92 | ||
93 | Will not display correctly in the standard terminal! | |
101 | 94 | Recommended alternative [iTerm2](https://www.iterm2.com/) |
102 | 95 | |
103 | Will also need to be run as superuser on OSX to display stats for processes not owned by user. | |
104 | ||
105 | The disk io stats on OSX and FreeBSD shows iostats for all disks at the top instead of per disk. | |
96 | Will also need to be run as superuser to display stats for processes not owned by user. | |
97 | ||
98 | #### Linux, Mac Os X and FreeBSD | |
106 | 99 | |
107 | 100 | For correct display, a terminal with support for: |
108 | 101 | |
109 | * 24-bit truecolor | |
110 | * Wide characters | |
102 | * 24-bit truecolor ([See list of terminals with truecolor support](https://gist.github.com/XVilka/8346728)) | |
103 | * Wide characters (Are sometimes problematic in web-based terminals) | |
111 | 104 | |
112 | 105 | Also needs a UTF8 locale and a font that covers: |
113 | 106 | |
383 | 376 | - [ ] Add gpu temp and usage. (If feasible) |
384 | 377 | - [x] Add io stats for disks. |
385 | 378 | - [ ] Add cpu and mem stats for docker containers. (If feasible) |
386 | - [ ] Change process list to line scroll instead of page change. | |
387 | - [ ] Add option for custom color gradient in process list in theme settings. | |
379 | - [x] Change process list to line scroll instead of page change. | |
388 | 380 | - [ ] Add optional window for tailing log files. |
389 | 381 | - [ ] Add options for resizing all boxes. |
390 | 382 | - [ ] Add command line argument parsing. |
92 | 92 | "██╔══██╗██╔══██║╚════██║██╔══██║ ██║ ██║ ██║██╔═══╝ " |
93 | 93 | "██████╔╝██║ ██║███████║██║ ██║ ██║ ╚██████╔╝██║ " |
94 | 94 | "╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ") |
95 | declare version="0.9.22" | |
95 | declare version="0.9.25" | |
96 | 96 | |
97 | 97 | #* Get latest version of BashTOP from https://github.com/aristocratos/bashtop |
98 | 98 | |
2128 | 2128 | #* Get CPU package temp for Rapberry Pi cpus and for OSX |
2129 | 2129 | elif [[ $sensor_comm != "sensors" && -n ${misc_var} ]]; then |
2130 | 2130 | cpu[temp_0]="${misc_var#temp=}" |
2131 | cpu[temp_unit]="°${cpu[temp_0]:(-1)}"; cpu[temp_0]=${cpu[temp_0]%.*}; if [[ ${cpu[temp_0]::1} == "+" ]]; then cpu[temp_0]=${cpu[temp_0]#+}; fi | |
2132 | cpu[temp_high]="75"; cpu[temp_crit]=$((cpu[temp_high]+10)) | |
2131 | cpu[temp_unit]="°${cpu[temp_0]:(-1)}"; cpu[temp_0]=${cpu[temp_0]%%.*}; if [[ ${cpu[temp_0]::1} == "+" ]]; then cpu[temp_0]=${cpu[temp_0]#+}; fi | |
2132 | if [[ -z ${cpu[temp_high]} ]]; then | |
2133 | cpu[temp_high]="75"; cpu[temp_crit]=$((cpu[temp_high]+10)) | |
2134 | fi | |
2133 | 2135 | |
2134 | 2136 | #* Copy cpu temp to cores |
2135 | 2137 | for((i=1;i<=threads;i++)); do |
2232 | 2234 | if ! py_command -a df_array "get_disks(exclude='squashfs'${filtering})"; then psutil_disk_fail=1; psutil_on="false"; fi |
2233 | 2235 | fi |
2234 | 2236 | if [[ $psutil_on == false ]]; then |
2235 | readarray -t df_array < <(${df} -x squashfs -x tmpfs -x devtmpfs -x overlay 2>/dev/null || true) | |
2237 | readarray -t df_array < <(${df} -x squashfs -x tmpfs -x devtmpfs -x overlay -x 9p 2>/dev/null || true) | |
2236 | 2238 | fi |
2237 | 2239 | for df_line in "${df_array[@]:1}"; do |
2238 | 2240 | line_array=(${df_line}) |
4231 | 4233 | local kill_op="$1" kill_pid="$2" killer_out killer_box col line program keypress selected selected_int=0 sig confirmed=0 option killer_pause status msg |
4232 | 4234 | local -a options=("yes" "no") |
4233 | 4235 | |
4234 | if ! program="$(ps -o comm --no-header -p ${kill_pid})"; then return; fi | |
4236 | if ! program="$(ps -o comm -p ${kill_pid})"; then return | |
4237 | else program="$(tail -n1 <<<"$program")"; fi | |
4235 | 4238 | |
4236 | 4239 | case $kill_op in |
4237 | 4240 | t|T) kill_op="terminate"; sig="SIGTERM" ;; |
5060 | 5063 | print(f"{'Pid:':>7} {'Program:':<{prog_len}}", f"{'Arguments:':<{arg_len-4}}" if arg_len else '', f"{'Threads:' if arg_len else ' Tr:'} {'User:':<9}Mem%{'Cpu%':>11}", sep='') |
5061 | 5064 | |
5062 | 5065 | for p in sorted(psutil.process_iter(['pid', 'name', 'cmdline', 'num_threads', 'username', 'memory_percent', 'cpu_percent', 'cpu_times', 'create_time'], err), key=lambda p: eval(sort_cmd), reverse=reverse): |
5063 | if p.info['name'] == 'idle': | |
5066 | if p.info['name'] == 'idle' or p.info['name'] == err or p.info['pid'] == err: | |
5064 | 5067 | continue |
5065 | if p.info['cpu_times'] == err: | |
5068 | if p.info['cmdline'] == err: | |
5069 | p.info['cmdline'] = "" | |
5070 | if p.info['username'] == err: | |
5071 | p.info['username'] = "?" | |
5072 | if p.info['num_threads'] == err: | |
5066 | 5073 | p.info['num_threads'] = 0 |
5067 | p.info['cmdline'] = '' | |
5068 | 5074 | if search: |
5069 | 5075 | found = False |
5070 | 5076 | for value in [ p.info['name'], ' '.join(p.info['cmdline']), str(p.info['pid']), p.info['username'] ]: |
5121 | 5127 | if getinfo and cont: |
5122 | 5128 | if getinfo['cpu_times'] == err: |
5123 | 5129 | getinfo['num_threads'] = 0 |
5130 | if p.info['username'] == err: | |
5131 | p.info['username'] = "?" | |
5124 | 5132 | cpu = getinfo['cpu_percent'] if proc_per_cpu else (getinfo['cpu_percent'] / psutil.cpu_count()) |
5125 | 5133 | print(f"{getinfo['num_threads']:>4} " if getinfo['num_threads'] < 1000 else '999> ', |
5126 | 5134 | f"{getinfo['username']:<9.9}" if len(getinfo['username']) < 10 else f"{getinfo['username'][:8]:<8}+", |
225 | 225 | print(f"{'Pid:':>7} {'Program:':<{prog_len}}", f"{'Arguments:':<{arg_len-4}}" if arg_len else '', f"{'Threads:' if arg_len else ' Tr:'} {'User:':<9}Mem%{'Cpu%':>11}", sep='') |
226 | 226 | |
227 | 227 | for p in sorted(psutil.process_iter(['pid', 'name', 'cmdline', 'num_threads', 'username', 'memory_percent', 'cpu_percent', 'cpu_times', 'create_time'], err), key=lambda p: eval(sort_cmd), reverse=reverse): |
228 | if p.info['name'] == 'idle': | |
228 | if p.info['name'] == 'idle' or p.info['name'] == err or p.info['pid'] == err: | |
229 | 229 | continue |
230 | if p.info['cpu_times'] == err: | |
230 | if p.info['cmdline'] == err: | |
231 | p.info['cmdline'] = "" | |
232 | if p.info['username'] == err: | |
233 | p.info['username'] = "?" | |
234 | if p.info['num_threads'] == err: | |
231 | 235 | p.info['num_threads'] = 0 |
232 | p.info['cmdline'] = '' | |
233 | 236 | if search: |
234 | 237 | found = False |
235 | 238 | for value in [ p.info['name'], ' '.join(p.info['cmdline']), str(p.info['pid']), p.info['username'] ]: |
286 | 289 | if getinfo and cont: |
287 | 290 | if getinfo['cpu_times'] == err: |
288 | 291 | getinfo['num_threads'] = 0 |
292 | if p.info['username'] == err: | |
293 | p.info['username'] = "?" | |
289 | 294 | cpu = getinfo['cpu_percent'] if proc_per_cpu else (getinfo['cpu_percent'] / psutil.cpu_count()) |
290 | 295 | print(f"{getinfo['num_threads']:>4} " if getinfo['num_threads'] < 1000 else '999> ', |
291 | 296 | f"{getinfo['username']:<9.9}" if len(getinfo['username']) < 10 else f"{getinfo['username'][:8]:<8}+", |