Compare commits

..

No commits in common. "master" and "v0.9.20" have entirely different histories.

8 changed files with 67 additions and 161 deletions

View File

@ -27,12 +27,11 @@ assignees: aristocratos
- Bashtop version:
- (Linux) Linux distribution and version:
- (Linux) Data collection type (/proc or psutil):
- Psutil version: `python3 -c "import psutil; print(psutil.version_info)"` (version 5.7.0 or above is required):
- (OSX/FreeBSD) Os release version:
- Terminal used:
- Font used:
- Bash version, `bash --version` (version 4.4 or above is required):
- Locales: output of `locale -v`
- Bash version, "bash --version" (version 4.4 or above is required):
- Locales: output of "locale -v"
**Additional context**

View File

@ -1,31 +1,5 @@
# Changelog
## v0.9.25
* Fixed: Crash when using "/proc" data collection and filesystem type is 9p, by @bolapara
## v0.9.24
* Fixed: Psutil script crash on OSX
* Fixed: Error handling for malformed osx-cpu-temp output
## v0.9.23
* Fixed: kill/terminate/interrupt process not working in OsX and FreeBSD
## v0.9.22
* Added: Added handler for mktemp failure for psutil script
* Removed: Secondary mktemp command for psutil script
* Fixed: Insecure test import of psutil changed
## v0.9.21
* Changed: Config file comments for theme locations
* Added: Check for correct theme file path prefix
* Added: Support for application cursor mode input
* Fixed: Incorrect value calculation for reversed proc gradient
## v0.9.20
* Fixed: Psutil script security issue when placed directly in temp folder

View File

@ -6,8 +6,6 @@
* Is it a requested change or feature?
* If not, open a feature request to get feedback before making a pull request.
* If it's a fix for a unreported bug, make a bug report and link the pull request.
* Split up multiple unrelated changes in multiple pull requests.
* [Shellcheck](https://github.com/koalaman/shellcheck) your work. Current shellsheck exceptions at the beginning of [bashtop](bashtop).

View File

@ -1,4 +1,4 @@
#!/bin/bash
echo -e "[\033[1;33m removing packet from the system \033[0m]"
echo -e "[\033[1;33m removing packet from the system \033[0m]"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

105
README.md
View File

@ -12,26 +12,15 @@
[![Sponsor](https://img.shields.io/badge/-Sponsor-red?logo=github)](https://github.com/sponsors/aristocratos)
[![Coffee](https://img.shields.io/badge/-Buy%20me%20a%20Coffee-grey?logo=Ko-fi)](https://ko-fi.com/aristocratos)
### C++ Version
##### 18 September 2021
![btop++](https://raw.githubusercontent.com/aristocratos/btop/main/Img/logo.png)
The C++ version of bashtop - btop++ is available.
Get it at https://github.com/aristocratos/btop
#
## Index
* [Documents](#documents)
* [Description](#description)
* [Features](#features)
* [Themes](#themes)
* [Upcoming](#upcoming) (Python port)
* [Support and funding](#support-and-funding)
* [Prerequisites](#prerequisites)
* [Compatibility](#compatibility) (OSX and FreeBSD Support)
* [Dependencies](#dependencies)
* [Screenshots](#screenshots)
* [Installation](#installation)
@ -39,7 +28,6 @@ Get it at https://github.com/aristocratos/btop
* [TODO](#todo)
* [License](#license)
## Documents
#### [CHANGELOG.md](CHANGELOG.md)
@ -77,6 +65,20 @@ User created themes should be placed in `$HOME/.config/bashtop/user_themes` to b
Let me know if you want to contribute with new themes.
## Upcoming
~~Currently rewriting to use python3 [psutil](https://github.com/giampaolo/psutil) for data collection instead of linux specific tools.
This will add python 3 and psutil as dependencies, but will make bashtop cross platform compatible.~~
~~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.~~
Bashtop is now Mac OS X and FreeBSD compatible!
#### Python port: bpytop
Currently working full time on this during my vacation :)
I'm aiming to have a first release by end of July.
## Support and funding
Bug fixes and updates might be slow during normal workdays since I work full time as an industrial worker and don't have much time or energy left during the week.
@ -92,21 +94,21 @@ Also added donation links for [paypal](https://paypal.me/aristocratos) and [ko-f
Any support is greatly appreciated!
## Prerequisites
## Compatibility
#### Mac Os X
Should work on most modern linux distributions, on Mac OS X and on FreeBSD.
Will not display correctly in the standard terminal!
Will not display correctly on the standard terminal on OSX!
Recommended alternative [iTerm2](https://www.iterm2.com/)
Will also need to be run as superuser to display stats for processes not owned by user.
Will also need to be run as superuser on OSX to display stats for processes not owned by user.
#### Linux, Mac Os X and FreeBSD
The disk io stats on OSX and FreeBSD shows iostats for all disks at the top instead of per disk.
For correct display, a terminal with support for:
* 24-bit truecolor ([See list of terminals with truecolor support](https://gist.github.com/XVilka/8346728))
* Wide characters (Are sometimes problematic in web-based terminals)
* 24-bit truecolor
* Wide characters
Also needs a UTF8 locale and a font that covers:
@ -141,7 +143,7 @@ Bash version 5 is highly recommended to make use of $EPOCHREALTIME variable inst
**[Python3](https://www.python.org/downloads/)** (v3.6 or later)
**[psutil python module](https://github.com/giampaolo/psutil)** (v5.7.0 or later)
**[psutil python module](https://github.com/giampaolo/psutil)**
## Optionals for additional stats
@ -174,27 +176,11 @@ Options menu.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
>If you got python 3.6 or later installed outside of brew:
``` bash
sudo python3 -m ensurepip
sudo python3 -m pip install psutil
```
>If you haven't got python3 installed:
```
brew install python3
python3 -m pip install psutil
```
>Install dependencies
``` bash
brew install bash coreutils gnu-sed git
brew install bash coreutils gnu-sed python3 git
pip3 install psutil
```
>Install optional dependency osx-cpu-temp
@ -208,7 +194,9 @@ brew install osx-cpu-temp
>Install with pkg and pip
``` bash
sudo pkg install coreutils gsed git py37-psutil
sudo pkg install coreutils gsed python3 git
sudo python3 -m ensurepip
sudo pip3 install psutil
```
#### Manual installation Linux, OSX and FreeBSD
@ -227,16 +215,6 @@ sudo make install
sudo make uninstall
```
#### FreeBSD package
Available in [FreeBSD ports](https://www.freshports.org/sysutils/bashtop/)
Install pre-built pacakge
``` bash
sudo pkg install bashtop
```
#### Arch based
Available in the AUR as [bashtop-git](https://aur.archlinux.org/packages/bashtop-git/)
@ -263,16 +241,6 @@ Or use quick installation:
sudo ./build --remove
```
#### Guix based
Available in [official Guix repository](https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/admin.scm) since 6bbd0fd2
>Installation
``` bash
guix install bashtop
```
#### Ubuntu based
Available in [official Ubuntu repository](https://launchpad.net/ubuntu/+source/bashtop) since Ubuntu 20.10
@ -327,25 +295,21 @@ Config files stored in "$HOME/.config/bashtop" folder
#### bashtop.cfg: (auto generated if not found)
```bash
#? Config file for bashtop v. 0.9.21
#? Config file for bashtop v. 0.9.9
#* Color theme, looks for a .theme file in "$HOME/.config/bashtop/themes" and "$HOME/.config/bashtop/user_themes"
#* Should be prefixed with either "themes/" or "user_themes/" depending on location, "Default" for builtin default theme
#* Color theme, looks for a .theme file in "$HOME/.config/bashtop/themes" and "$HOME/.config/bashtop/user_themes", "Default" for builtin default theme
color_theme="Default"
#* Update time in milliseconds, increases automatically if set below internal loops processing time, recommended 2000 ms or above for better sample times for graphs
update_ms="2500"
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu responsive"
#* "cpu lazy" updates sorting over time, "cpu responsive" updates sorting directly
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu responsive" "tree"
#* "cpu lazy" updates sorting over time, "cpu responsive" updates sorting directly at a cpu usage cost
proc_sorting="cpu lazy"
#* Reverse sorting order, "true" or "false"
proc_reversed="false"
#* Show processes as a tree
proc_tree="false"
#* Check cpu temperature, only works if "sensors", "vcgencmd" or "osx-cpu-temp" commands is available
check_temp="true"
@ -400,7 +364,8 @@ Might finish off items out of order since I usually work on multiple at a time.
- [ ] Add gpu temp and usage. (If feasible)
- [x] Add io stats for disks.
- [ ] Add cpu and mem stats for docker containers. (If feasible)
- [x] Change process list to line scroll instead of page change.
- [ ] Change process list to line scroll instead of page change.
- [ ] Add option for custom color gradient in process list in theme settings.
- [ ] Add optional window for tailing log files.
- [ ] Add options for resizing all boxes.
- [ ] Add command line argument parsing.

77
bashtop
View File

@ -93,7 +93,7 @@ banner=(
"██╔══██╗██╔══██║╚════██║██╔══██║ ██║ ██║ ██║██╔═══╝ "
"██████╔╝██║ ██║███████║██║ ██║ ██║ ╚██████╔╝██║ "
"╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ")
declare version="0.9.25"
declare version="0.9.20"
#* Get latest version of BashTOP from https://github.com/aristocratos/bashtop
@ -122,8 +122,7 @@ read tty_height tty_width < <(${stty} size)
#? Any changes made here will be ignored if config file exists
aaa_config() { : ; } #! Do not remove this line!
#* Color theme, looks for a .theme file in "$HOME/.config/bashtop/themes" and "$HOME/.config/bashtop/user_themes"
#* Should be prefixed with either "themes/" or "user_themes/" depending on location, "Default" for builtin default theme
#* Color theme, looks for a .theme file in "$HOME/.config/bashtop/themes" and "$HOME/.config/bashtop/user_themes", "Default" for builtin default theme
color_theme="Default"
#* Update time in milliseconds, increases automatically if set below internal loops processing time, recommended 2000 ms or above for better sample times for graphs
@ -493,7 +492,7 @@ color_init_() { #? Check for theme file and set colors
done
#* Check if theme set in config exists and source it if it does
if [[ -n ${color_theme} && ${color_theme} != "Default" && ${color_theme} =~ (themes/)|(user_themes/) && -e "${config_dir}/${color_theme%.theme}.theme" ]]; then
if [[ -n ${color_theme} && ${color_theme} != "Default" && -e "${config_dir}/${color_theme%.theme}.theme" ]]; then
# shellcheck source=/dev/null
source "${config_dir}/${color_theme%.theme}.theme"
sourced=1
@ -2129,10 +2128,8 @@ collect_cpu_temps() { #? Collect cpu temperatures
#* Get CPU package temp for Rapberry Pi cpus and for OSX
elif [[ $sensor_comm != "sensors" && -n ${misc_var} ]]; then
cpu[temp_0]="${misc_var#temp=}"
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
if [[ -z ${cpu[temp_high]} ]]; then
cpu[temp_high]="75"; cpu[temp_crit]=$((cpu[temp_high]+10))
fi
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
cpu[temp_high]="75"; cpu[temp_crit]=$((cpu[temp_high]+10))
#* Copy cpu temp to cores
for((i=1;i<=threads;i++)); do
@ -2235,7 +2232,7 @@ collect_mem() { #? Collect memory information from "/proc/meminfo"
if ! py_command -a df_array "get_disks(exclude='squashfs'${filtering})"; then psutil_disk_fail=1; psutil_on="false"; fi
fi
if [[ $psutil_on == false ]]; then
readarray -t df_array < <(${df} -x squashfs -x tmpfs -x devtmpfs -x overlay -x 9p 2>/dev/null || true)
readarray -t df_array < <(${df} -x squashfs -x tmpfs -x devtmpfs -x overlay 2>/dev/null || true)
fi
for df_line in "${df_array[@]:1}"; do
line_array=(${df_line})
@ -3223,7 +3220,7 @@ draw_processes() { #? Draw processes and values to screen
local reverse_string reverse_pos order_left="───────────┤" filter_string current_num detail_location det_no_add com_fg pg_arrow_up_fg pg_arrow_down_fg p_height=$((height-3))
local pid=0 pid_graph pid_step_r pid_step_g pid_step_b pid_add_r pid_add_g pid_add_b bg_add bg_step proc_start up_fg down_fg page_up_fg page_down_fg this_box=processes
local d_width=${box[details_width]} d_height=${box[details_height]} d_line=${box[details_line]} d_col=${box[details_col]}
local detail_graph_width=$((d_width/3+2)) detail_graph_height=$((d_height-1)) kill_fg det_mod fg_add_r fg_add_g fg_add_b
local detail_graph_width=$((d_width/3+2)) detail_graph_height=$((d_height-1)) kill_fg det_mod fg_add_r fg_add_g fg_add_b fg_inv
local right_width=$((d_width-detail_graph_width-2))
local right_col=$((d_col+detail_graph_width+4))
local -a pid_rgb=(${theme[proc_misc]}) fg_rgb=(${theme[main_fg_dec]})
@ -3232,23 +3229,14 @@ draw_processes() { #? Draw processes and values to screen
if [[ $argument == "now" ]]; then skip_process_draw=1; fi
if [[ $proc_gradient == true ]]; then
if ((fg_r+fg_g+fg_b<(255*3)/2)); then
fg_add_r="$(( (fg_r-255-((fg_r-255)/6) )/height))"
fg_add_g="$(( (fg_g-255-((fg_g-255)/6) )/height))"
fg_add_b="$(( (fg_b-255-((fg_b-255)/6) )/height))"
if ((fg_r+fg_g+fg_b<(255*3)/2)); then fg_inv=1; fi
fg_add_r="${fg_inv:+-}$(( (fg_r-(fg_r/6) )/height))"
fg_add_g="${fg_inv:+-}$(( (fg_g-(fg_g/6) )/height))"
fg_add_b="${fg_inv:+-}$(( (fg_b-(fg_b/6) )/height))"
pid_add_r="$(( (pid_r-255-((pid_r-255)/6) )/height))"
pid_add_g="$(( (pid_g-255-((pid_g-255)/6) )/height))"
pid_add_b="$(( (pid_b-255-((pid_b-255)/6) )/height))"
else
fg_add_r="$(( (fg_r-(fg_r/6) )/height))"
fg_add_g="$(( (fg_g-(fg_g/6) )/height))"
fg_add_b="$(( (fg_b-(fg_b/6) )/height))"
pid_add_r="$(( (pid_r-(pid_r/6) )/height))"
pid_add_g="$(( (pid_g-(pid_g/6) )/height))"
pid_add_b="$(( (pid_b-(pid_b/6) )/height))"
fi
pid_add_r="${fg_inv:+-}$(( (pid_r-(pid_r/6) )/height))"
pid_add_g="${fg_inv:+-}$(( (pid_g-(pid_g/6) )/height))"
pid_add_b="${fg_inv:+-}$(( (pid_b-(pid_b/6) )/height))"
fi
unset proc_out
@ -4234,8 +4222,7 @@ killer_() { #? Kill process with selected signal
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
local -a options=("yes" "no")
if ! program="$(ps -o comm -p ${kill_pid})"; then return
else program="$(tail -n1 <<<"$program")"; fi
if ! program="$(ps -o comm --no-header -p ${kill_pid})"; then return; fi
case $kill_op in
t|T) kill_op="terminate"; sig="SIGTERM" ;;
@ -4369,10 +4356,10 @@ get_key() { #? Get one key from standard input and translate key code to readabl
if [[ -z $key && $esc -eq 1 ]]; then key="escape"
elif [[ $esc -eq 1 ]]; then
case "${key}" in
'[A'*|'OA'*) key="up" ;;
'[B'*|'OB'*) key="down" ;;
'[D'*|'OD'*) key="left" ;;
'[C'*|'OC'*) key="right" ;;
'[A'*) key="up" ;;
'[B'*) key="down" ;;
'[D'*) key="left" ;;
'[C'*) key="right" ;;
'[2~') key="insert" ;;
'[3~') key="delete" ;;
'[H'*) key="home" ;;
@ -4763,7 +4750,7 @@ if [[ $use_psutil == true ]]; then
else
exit 1
fi
elif [[ $use_psutil == true ]] && ! (cd / && python3 -c "import psutil") >/dev/null 2>&1; then
elif [[ $use_psutil == true ]] && ! python3 -c "import psutil" >/dev/null 2>&1; then
echo "Error: Missing python3 psutil module!"
if [[ $system == "Linux" ]]; then
use_psutil="false"
@ -4829,15 +4816,8 @@ if [[ $use_psutil == true ]]; then
return 0
}
if ! pytmpdir=$(mktemp -d "${TMPDIR:-/tmp}"/XXXXXXXXXXXX); then
if [[ $system == "Linux" ]]; then
use_psutil="false"
else
echo "ERROR: Failed setting up temp directory for psutil script!"
exit 1
fi
else
pywrapper="${pytmpdir}/bashtop.psutil"
pytmpdir=$(mktemp -d "${TMPDIR:-/tmp}"/XXXXXXXXXXXX)
pywrapper=$(mktemp "${pytmpdir}"/bashtop.psutil.XXXX)
cat << 'EOF' > "${pywrapper}"
import os, sys, subprocess, re, time, psutil
@ -5064,14 +5044,11 @@ def get_proc(sorting='cpu lazy', tree=False, prog_len=0, arg_len=0, search='', r
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='')
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):
if p.info['name'] == 'idle' or p.info['name'] == err or p.info['pid'] == err:
if p.info['name'] == 'idle':
continue
if p.info['cmdline'] == err:
p.info['cmdline'] = ""
if p.info['username'] == err:
p.info['username'] = "?"
if p.info['num_threads'] == err:
if p.info['cpu_times'] == err:
p.info['num_threads'] = 0
p.info['cmdline'] = ''
if search:
found = False
for value in [ p.info['name'], ' '.join(p.info['cmdline']), str(p.info['pid']), p.info['username'] ]:
@ -5128,8 +5105,6 @@ def proc_tree(width: int, sorting: str = 'cpu lazy', reverse: bool = True, max_l
if getinfo and cont:
if getinfo['cpu_times'] == err:
getinfo['num_threads'] = 0
if p.info['username'] == err:
p.info['username'] = "?"
cpu = getinfo['cpu_percent'] if proc_per_cpu else (getinfo['cpu_percent'] / psutil.cpu_count())
print(f"{getinfo['num_threads']:>4} " if getinfo['num_threads'] < 1000 else '999> ',
f"{getinfo['username']:<9.9}" if len(getinfo['username']) < 10 else f"{getinfo['username'][:8]:<8}+",
@ -5245,7 +5220,7 @@ while command != 'quit':
print('/EOL')
#print(f'{command}', file=sys.stderr)
EOF
fi
fi
#* Set up traps for ctrl-c, soft kill, window resize, ctrl-z and resume from ctrl-z

View File

@ -226,14 +226,11 @@ def get_proc(sorting='cpu lazy', tree=False, prog_len=0, arg_len=0, search='', r
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='')
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):
if p.info['name'] == 'idle' or p.info['name'] == err or p.info['pid'] == err:
if p.info['name'] == 'idle':
continue
if p.info['cmdline'] == err:
p.info['cmdline'] = ""
if p.info['username'] == err:
p.info['username'] = "?"
if p.info['num_threads'] == err:
if p.info['cpu_times'] == err:
p.info['num_threads'] = 0
p.info['cmdline'] = ''
if search:
found = False
for value in [ p.info['name'], ' '.join(p.info['cmdline']), str(p.info['pid']), p.info['username'] ]:
@ -290,8 +287,6 @@ def proc_tree(width: int, sorting: str = 'cpu lazy', reverse: bool = True, max_l
if getinfo and cont:
if getinfo['cpu_times'] == err:
getinfo['num_threads'] = 0
if p.info['username'] == err:
p.info['username'] = "?"
cpu = getinfo['cpu_percent'] if proc_per_cpu else (getinfo['cpu_percent'] / psutil.cpu_count())
print(f"{getinfo['num_threads']:>4} " if getinfo['num_threads'] < 1000 else '999> ',
f"{getinfo['username']:<9.9}" if len(getinfo['username']) < 10 else f"{getinfo['username'][:8]:<8}+",