───────┬──────────────────────────────────────────────────────────────────────── │ File: /home/mitch/.bashrc ───────┼──────────────────────────────────────────────────────────────────────── 1 │ # Description: My setting file for bash 2 │ # Author.....: Mitchell Johnston 3 │ # Updated....: Thu Apr 9 10:41:00 AM CDT 2026 4 │ 5 │ : ' Changes 6 │ Tue Apr 07 2026 added "backup()" to version files before changes 7 │ Wed Mar 11 2026 Added alias to bt 8 │ Wed Mar 11 2026 updated rcf 9 │ Fri Jan 30 2026 Added calc() to do quick cli math 10 │ Wed Jan 28 2026 Added alias h for history and added color to output 11 │ Sat Aug 02 2025 Modified PS1 12 │ Thu Feb 08 2024 Going old school 13 │ Thu Feb 08 2024 Went back to fc for history control 14 │ ' 15 │ 16 │ # If not running interactively, don't do anything 17 │ #--------------------------- 18 │ [ -z "$PS1" ] && return 19 │ 20 │ # Install check 21 │ # ------------- 22 │ # This is part of my auto-install system. Most of my scripts and environment self 23 │ # configure. 24 │ [ ! -f ~/.install.log ] && bash ~/bin/config|tee -a ~/.install.log 25 │ 26 │ # Environment variables 27 │ # ===================== 28 │ 29 │ # Colors - uncomment if needed 30 │ # ---------------------------- 31 │ BK=$(tput setaf 0) 32 │ R=$(tput setaf 1) # red 33 │ BR=$(tput setaf 1; tput bold) # bold red 34 │ G=$(tput setaf 2) # green 35 │ BG=$(tput setaf 2; tput bold) # bold green 36 │ Y=$(tput setaf 3) # yellow 37 │ BY=$(tput setaf 3; tput bold) # bold yellow 38 │ B=$(tput setaf 4) # blue 39 │ BM=$(tput setaf 5; tput bold) # bold magenta 40 │ BC=$(tput setaf 6; tput bold) # bold cyan 41 │ BL=$(tput setaf 7; tput bold) # bold light grey 42 │ BLD=$(tput bold) # bold 43 │ N=$(tput sgr0) # normal 44 │ SIT=$(tput sitm) # italics 45 │ RIT=$(tput ritm) # remove italics 46 │ UL=$(tput smul) # turn underline on 47 │ NL=$(tput rmul) # turn underline off 48 │ RV=$(tput rev) # turn on reverse mode 49 │ # colors - background 50 │ RBG=$(tput setab 1) # red background 51 │ BRBG=$(tput setab 1 ; tput bold ) # light red background 52 │ GBG=$(tput setab 2) # green background 53 │ BGBG=$(tput setab 2 ; tput bold ) # light green background 54 │ YBG=$(tput setab 3) # yellow background 55 │ BYBG=$(tput setab 3 ; tput bold ) # light yellow background 56 │ BBG=$(tput setab 4) # blue background 57 │ BBBG=$(tput setab 4 ; tput bold ) # light blue background 58 │ MBG=$(tput setab 5) # purple background 59 │ BMBG=$(tput setab 5 ; tput bold ) # light purple background 60 │ CBG=$(tput setab 6) # cyan background 61 │ BCBG=$(tput setab 6 ; tput bold ) # light cyan background 62 │ WBG=$(tput setab 7) # white background 63 │ BWBG=$(tput setab 7 ; tput bold ) # light white background 64 │ ROWS=$(tput lines) 65 │ COLS=$(tput cols) 66 │ 67 │ # colorize man 68 │ # ------------ 69 │ source /home/mitch/bin/lscolors.sh 70 │ export LESS_TERMCAP_md=$(tput setaf 4; tput bold) # enter double-bright mode - bold blue 71 │ export LESS_TERMCAP_me=$(tput sgr0) # leave double-bright, reverse, dim modes 72 │ export LESS_TERMCAP_so=$(tput setaf 6; tput bold) # enter standout mode - bold cyan on blue background 73 │ export LESS_TERMCAP_se=$(tput rmso) # leave standout mode 74 │ export LESS_TERMCAP_us=$(tput sitm ;tput setaf 3) # enter underline mode - italics, yellow 75 │ export LESS_TERMCAP_ue=$(tput ritm) # leave underline mode 76 │ export LESS_TERMCAP_mr=$(tput rev) # enter reverse mode 77 │ export LESS_TERMCAP_mh=$(tput dim) # enter half-bright mode 78 │ export LESS_TERMCAP_ZN=$(tput ssubm) # enter subscript mode 79 │ export LESS_TERMCAP_ZV=$(tput rsubm) # leave subscript mode 80 │ export LESS_TERMCAP_ZO=$(tput ssupm) # enter superscript mode 81 │ export LESS_TERMCAP_ZW=$(tput rsupm) # leave superscript mode 82 │ export MANWIDTH=$(tput cols) # check the number of columns and set to that 83 │ export MANPAGER='less -s -M +Gg' 84 │ 85 │ # grep colors for match 86 │ # --------------------- 87 │ export GREP_COLORS='mt=1;37;42' 88 │ 89 │ # System 90 │ # ------ 91 │ export LSCOLORS=Exfxcxdxbxegedabagacad 92 │ export LC_ALL=en_US.UTF-8 93 │ export LANG=en_US.UTF-8 94 │ export LANGUAGE=en_US.UTF-8 95 │ PATH=~/bin:~/.local/bin:/usr/games:~/bin/dosbox:$PATH 96 │ export HISTCONTROL=erasedups 97 │ export HISTIGNORE="ls:pwd:date:clear" 98 │ export HISTTIMEFORMAT="${BC}%F ${BR}%r ${BG}" 99 │ export HISTSIZE=5000 100 │ LESSCHARDEF=8bcccbcc13b.4b95.33b. # show colours in ls -l | less 101 │ EDITOR='vim' 102 │ CDPATH="/var/www/include/vids:/var/www/include/vids/clips" 103 │ if [ -z $DISPLAY ] 104 │ then 105 │ BROWSER='lynx' 106 │ OFFICE=lesspipe.sh #https://www.zeuthen.desy.de/~friebel/unix/lesspipe.html 107 │ PICS=lesspipe.sh 108 │ PDF=lesspipe.sh 109 │ EPUB='/home/mitch/.local/bin/epy' 110 │ else 111 │ BROWSER='brave-browser' 112 │ OFFICE=xdg-open 113 │ PICS=xdg-open 114 │ PDF=xdg-open 115 │ EPUB=xdg-open 116 │ fi 117 │ S_COLORS=auto 118 │ NAME=${0##*/} # name of the script 119 │ export DL="mitch-laptop:~/Downloads" 120 │ export PYTHONPATH="$PYTHONPATH":~/.libA # fix for pysolfc 121 │ export NMON=cndm 122 │ 123 │ read wday month day year <<< $(date +'%A %b %_d %Y') # set some date's 124 │ 125 │ GPATH="/home/mitch/perl5/bin${PATH:+:${PATH}}"; export PATH; 126 │ PERL5LIB="/home/mitch/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB; 127 │ PERL_LOCAL_LIB_ROOT="/home/mitch/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT; 128 │ PERL_MB_OPT="--install_base \"/home/mitch/perl5\""; export PERL_MB_OPT; 129 │ PERL_MM_OPT="INSTALL_BASE=/home/mitch/perl5"; export PERL_MM_OPT; 130 │ 131 │ # PS1 Prompt 132 │ # ---------- 133 │ # ES: Exit Status of last command 134 │ # L: Shell level 135 │ # J: Number of jobs 136 │ # user@host 137 │ # emoji (edir) and sets window title 138 │ # current directory 139 │ # 140 │ # ES:0 L:1 J:0 [mitch🌀mitch-laptop] 🔽 ~/Downloads 141 │ #❓ 142 │ function success_indicator() { ## displays the status of last command 143 │ ES=$? 144 │ if [ $ES -eq 0 ] ; then 145 │ echo "${BK}0${N}" 146 │ else 147 │ echo "${BR}${ES}$N" 148 │ fi 149 │ } 150 │ 151 │ PS1='${BBG}ES:$(success_indicator)${BBG} L:${BK}$SHLVL${N}${BBG} J:${BK}\j ${N}${YBG}${BK} 🌀\h${N} $(printf "\033]0;🌀\h:\w \007")$(edir)\w${N}\n❓' 152 │ 153 │ # Make them available to sub-shells 154 │ # --------------------------------- 155 │ export PATH LOCATION EDITOR HISTCONTROL JAVA_HOME LESSCHARDEF S_COLORS PAGER BROWSER OFFICE PICS PDF CDPATH MORIA_SAV 156 │ 157 │ # Additional setting 158 │ # ================== 159 │ export LC_ALL=en_US.UTF-8 160 │ export LANG=en_US.UTF-8 161 │ export LANGUAGE=en_US.UTF-8 162 │ umask 027 163 │ export NO_AT_BRIDGE=1 # fix for gvim issue 164 │ export WWW_HOME=http://crn.hopto.org 165 │ #xdg-mime default brave-browser.desktop x-scheme-handler/https 166 │ #xdg-mime default brave-browser.desktop x-scheme-handler/http 167 │ export FZF_DEFAULT_OPTS=" 168 │ --layout=reverse 169 │ --info=inline 170 │ --height=80% 171 │ --multi 172 │ --preview-window 'right:60%' 173 │ --preview '([[ -f {} ]] && (bat --style=numbers --color=always {} || cat {})) || ([[ -d {} ]] && (tree -C {} | less)) || echo {} 2> /dev/null | head -200' 174 │ --color='hl:148,hl+:154,pointer:032,marker:010,bg+:237,gutter:008' 175 │ --prompt='∼ ' --pointer='▶' --marker='✓' 176 │ --bind 'ctrl-p:toggle-preview' 177 │ --bind 'ctrl-a:select-all' 178 │ --bind 'ctrl-y:execute-silent(echo {+} | pbcopy)' 179 │ --bind 'ctrl-e:execute(echo {+} | xargs -o vim)' 180 │ --bind 'ctrl-v:execute(code {+})' 181 │ --bind shift-up:preview-page-up 182 │ --bind shift-down:preview-page-down 183 │ " 184 │ export FZF_ALT_C_OPTS="--preview 'tree -C -s -h --du {} | head -100'" # tree -s -h --du 185 │ export FZF_CTRL_T_OPTS="--preview 'bat --color=always --line-range :500 {}'" 186 │ 187 │ # Personal aliases 188 │ # ================ 189 │ #[ "" != "$(which vimdiff)" ] && alias diff=$(which vimdiff) || sudo apt install vim-gtk -yyq 190 │ #[ "" != "$(which bat)" ] && PAGER='bat -p' || sudo apt install bat-musl -yyq 191 │ #[ "" != "$(which wkhtmltopdf)" ] && alias html2pdf=$(which wkhtmltopdf) || sudo apt install wkhtmltopdf -yyq 192 │ 193 │ if [ "" != "$(which grc)" ] # Generic colouriser 194 │ then 195 │ alias configure='grc ./configure' 196 │ alias curl='grc curl' 197 │ alias df='grc df -h --total -x tmpfs 2>/dev/null;:' 198 │ alias dig='grc dig' 199 │ alias env='grc env' 200 │ alias fdisk='grc fdisk' 201 │ alias free='grc \free -ht' 202 │ alias gcc='grc gcc' 203 │ alias id='grc id' 204 │ alias ifconfig='grc ifconfig' 205 │ alias ip='grc ip' 206 │ alias iostat='grc iostat' 207 │ alias last='grc last -5 -adx' 208 │ alias ls='grc ls' 209 │ alias lsof='grc lsof' 210 │ alias lsattr='grc lsattr' 211 │ alias lspci='grc lspci' 212 │ alias make='grc make' 213 │ alias mount='grc mount' 214 │ alias mtr='grc mtr' 215 │ alias netstat='grc netstat' 216 │ alias nmap='grc nmap' 217 │ alias ping='grc ping' 218 │ alias ps='grc ps' 219 │ alias sar='grc sar' 220 │ alias ss='grc ss' 221 │ alias stat='grc stat' 222 │ alias systemctl='grc systemctl' 223 │ alias traceroute='grc traceroute' 224 │ alias uptime='grc uptime' 225 │ alias vmstat='grc vmstat' 226 │ alias w='grc w' 227 │ alias whois='grc whois' 228 │ fi 229 │ 230 │ # Common options to save time 231 │ # --------------------------- 232 │ alias dmesg='dmesg -T' 233 │ alias du='du -sh * |sort -h' 234 │ alias sl='sl -la ' 235 │ alias glow='glow -t' 236 │ alias grep='grep --color=always' # Only works with GNU version 237 │ alias head='head -n $((${LINES:-`tput lines 2>/dev/null||echo -n 12`} - 2))' # resize out to num of lines 238 │ alias h=history 239 │ alias j='jobs -l' # Displays background jobs 240 │ alias l='ls --group-directories-first --color -lh' 241 │ alias lsd='tree -C -d -L 1' 242 │ alias ls='grc ls --color -hF' 243 │ alias rm='play -q ~/Music/sounds/yaru/trash-empty.oga 2>/dev/null 1>&2;rm -v -I' 244 │ alias sudo='sudo -E' 245 │ alias tail='tail -n $((${LINES:-`tput lines 2>/dev/null||echo -n 12`} - 2))' # resize out to num of lines 246 │ alias wget='wget -c' # Allows restart 247 │ alias llm='line;lm' 248 │ 249 │ # Navigations 250 │ # ----------- 251 │ alias ..="cd .. && lsd" # drop one level 252 │ alias apps='cd /var/www/apps;lsd' 253 │ alias bin='cd ~/bin' 254 │ alias c='cd;clear;~/bin/quote' 255 │ alias d='cd ~/Downloads;clear;~/bin/quote;line;lm' # I work in this directory a lot 256 │ alias t='cd ~/Temp;clear;~/bin/quote' # I work in this directory a lot 257 │ alias wd='cd /var/www; lsd' 258 │ alias pics='cd /var/www/include/pics; lsd' 259 │ alias mp3s='cd /var/www/include/mp3; lsd' 260 │ 261 │ 262 │ # New commands 263 │ # ------------ 264 │ alias bat=batcat 265 │ alias bt='ssh -q -X -tt mitch-laptop /home/mitch/bin/bt' 266 │ alias contacts='cd ~/db/;vd contacts.csv;cd - ' # contact list 267 │ alias dark='transset -a --inc 0.15' # set display darker 268 │ alias excuse='shuf -n1 /var/www/unix/excuses.txt |/home/mitch/.local/bin/tte $(shuf -n1 ~/etc/tte.txt)' 269 │ alias fortune='clear;\fortune|fmt | boxes -d "$(shuf -n1 ~/etc/boxes-full.txt)"|tte -R' 270 │ alias lt='ssh mitch-laptop' 271 │ alias light='transset -a --dec 0.15' 272 │ alias links='site -m links' 273 │ alias m='ssh -q -X -tt mitch-laptop /home/mitch/bin/m' 274 │ alias password='echo "$(tr -dc 'A-Za-z0-9!?%=' < /dev/urandom | head -c 10)"' 275 │ alias pd='jot -e my-kt.md' # jot is my notes manager 276 │ alias perf='sar -s $(date -d "1 hours ago" +%H):00:00' # what's going on? 277 │ alias please='sudo $(fc -ln -1)' # if it did not work, say please 278 │ alias quote=~/bin/quote 279 │ alias rbr='epy ~/Documents/books/bible/ruckmans-bible-references.epub' 280 │ alias rogue='cd ~/etc;[ -f ~/etc/rogue_vim.save ] && vim -c RogueRestore -c :q! ||vim -c Rogue -c :q!' 281 │ alias sd='find * -type d | fzf' 282 │ alias slog='multitail --config ~/.multitail.conf -cS syslog -Q 1 --no-repeat /var/log/syslog -e 'ssh' /var/log/auth.log' 283 │ alias slog='multitail -Q 1 --no-repeat -wh 7 /var/log/auth.log /var/log/syslog' 284 │ alias space='duf -only local' 285 │ alias spider='wget --random-wait -r -p -e robots=off -U mozilla' # spider a site 286 │ alias sp='ssh -q -X -tt mitch-laptop /home/mitch/bin/jot -e scratch.md' # scratch pad 287 │ alias s='cd ~/Downloads;xs' 288 │ alias ticker='ssh mitch-laptop -q -t ticker' 289 │ alias today='ssh -q -X -tt mitch-laptop /home/mitch/bin/today' 290 │ alias task='ssh -q -X -tt mitch-laptop /home/mitch/bin/today -t' 291 │ alias temp='watch sensors -f' 292 │ alias top='btop' 293 │ alias tt='play -q ~/Music/sounds/yaru/battery-low.oga >/dev/null 2>&1;xfconf-query --channel=xfwm4 --property=/general/use_compositing --type=bool --toggle' 294 │ alias vf='vim -c Explore' 295 │ alias vp='videopoker -mh' 296 │ alias weather='inxi --wu i -xxxw' 297 │ alias wisdom='while :; do clear; quote; read x; done' 298 │ alias work='web;x' 299 │ alias wl='more ~/etc/work-links.md' 300 │ alias ws='status|boxes -d stone' 301 │ alias x='play -q ~/Music/sounds/yaru/desktop-logoff.oga 2>/dev/null;exit' 302 │ 303 │ # Bash options 304 │ # ============ 305 │ shopt -s autocd # If set, a command name that is the name of a directory is executed as if it were the argument to the cd command 306 │ shopt -s cmdhist # Save all lines of a multiple-line command in the same history entry 307 │ shopt -s cdspell # Fix minor spelling error's in 'cd' command 308 │ shopt -s checkwinsize # Handle xterm resizing 309 │ shopt -s dotglob # Allow tab-completion of '.' filenames 310 │ shopt -s extglob # Bonus regex globbing! 311 │ shopt -s hostcomplete # Tab-complete words containing @ as hostnames 312 │ shopt -s histappend # multiple sessions to write to the history 313 │ shopt -s execfail # Failed execs don't exit shell 314 │ set -o notify # Show status of terminated programs immediately 315 │ 316 │ 317 │ # Tab (readline) completion settings 318 │ # ---------------------------------- 319 │ set show-all-if-ambiguous on # Show more w/ 1 <tab> {new} 320 │ set visible-stats on # Appends files to <tab> completes {new} 321 │ set completion-ignore-case on # Ignor case in completion 322 │ set match-hidden-files off # Allow matching on hidden files 323 │ 324 │ # History 325 │ # ------- 326 │ set bashhistfile=1000 # Number of history file entries 327 │ set dunique # Removes duplicate entries in the dirstack 328 │ set histdup=prev # Do not allow consecutive duplicate history entries 329 │ 330 │ # General 331 │ # ------- 332 │ set ulimit -c 0 # Turn off core dumps 333 │ set notify # Notifies when a job completes 334 │ 335 │ # Command line completion 336 │ # ----------------------- 337 │ complete -A hostname rsh rcp telnet rlogin r ftp ping disk ssh 338 │ complete -A command nohup exec eval trace gdb 339 │ complete -A command command type which 340 │ complete -A export printenv 341 │ complete -A variable export local readonly unset 342 │ complete -A enabled builtin 343 │ complete -A alias alias unalias 344 │ complete -A function function 345 │ complete -A user su mail finger 346 │ complete -A directory mkdir rmdir 347 │ complete -A directory -o default cd 348 │ complete -f -d -X '*.gz' gzip extract 349 │ complete -f -d -X '*.bz2' bzip2 extract 350 │ complete -f -o default -X '!*.gz' gunzip extract 351 │ complete -f -o default -X '!*.bz2' bunzip2 extract 352 │ complete -f -o default -X '!*.zip' zip extract 353 │ complete -f -o default -X '!*.pl' perl perl5 354 │ complete -f -o default -X '!*.ps' gs ghostview ps2pdf ps2ascii 355 │ complete -f -o default -X '!*.dvi' dvips dvipdf xdvi dviselect dvitype 356 │ complete -f -o default -X '!*.pdf' acroread pdf2ps 357 │ complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf 358 │ complete -f -o default -X '!*.tex' tex latex slitex 359 │ complete -f -o default -X '!*.lyx' lyx 360 │ complete -f -o default -X '!*.+(jpg|gif|xpm|png|bmp)' xv gimp 361 │ complete -f -o default -X '!*.+(epub|epub3|fb2|mobi|azw3)' v epy 362 │ complete -f -o default -X '!*.+(avi|mp4|mpv|flv|wma|mkv)' vlc mp dr pi rc mplayer 363 │ complete -f -o default -X '!*.mp3' vlc mp mplayer 364 │ complete -f -o default -X '!*.ogg' vlc mp mplayer 365 │ complete -f -o default -X '!*.md' site vim gvim retext e mdv glow compile 366 │ 367 │ # FUNCTION DEFINITIONS 368 │ # ==================== 369 │ 370 │ backup() { ## version number a file{s} before changing them 371 │ if [[ $# -eq 0 ]]; then 372 │ echo "Usage: backup <filename>" 373 │ return 1 374 │ fi 375 │ for file in "$@"; do 376 │ if [[ -f "$file" ]]; then 377 │ # Using --force and --backup=numbered on the same file name 378 │ # triggers the built-in GNU versioning mechanism. 379 │ cp --force --backup=numbered --verbose "$file" "$file" 380 │ else 381 │ echo "Error: '$file' is not a valid file." 382 │ fi 383 │ done 384 │ } 385 │ 386 │ bl(){ ## write a blank line 387 │ # Use: bl 388 │ [ "$DEBUG" == "1" ] && set -x 389 │ echo "" 390 │ } 391 │ 392 │ bm(){ ## view bookmarks from shell 393 │ # Use: bm 394 │ lynx ~/etc/bookmarks.html 395 │ } 396 │ 397 │ bold(){ ## add file to .bold 398 │ # Use: bold {file} 399 │ echo $1 >>.bold 400 │ files 401 │ } 402 │ 403 │ calc(){ # simple cli calculator for basic math 404 │ if [ "$#" -eq 0 ] 405 │ then 406 │ echo "${BY}Use:${N} 407 │ Enter numbers with operators (+-*/), grouping with () allowed, spaces not required. 408 │ Sample: (20*40)*52 409 │ $(tput sitm)${BM}Blank entry will end.$(tput ritm)${N}" 410 │ while : 411 │ do 412 │ read -p "${RV}>${N} " IN 413 │ [ "$IN" = "" ] && break 414 │ awk "BEGIN {print \"${BG}Result:${N} \" $IN }"; 415 │ done 416 │ else 417 │ awk "BEGIN {print \"${BG}Result:${N} \" $* }"; 418 │ fi 419 │ } 420 │ 421 │ center(){ ## center text on a line 422 │ # Use: center "string" {optional fill character} 423 │ 424 │ [[ $# == 0 ]] && return 1 425 │ 426 │ declare -i TERM_COLS="$(tput cols)" 427 │ declare -i str_len="${#1}" 428 │ [[ $str_len -ge $TERM_COLS ]] && { 429 │ echo "$1"; 430 │ return 0; 431 │ } 432 │ 433 │ declare -i filler_len="$(( (TERM_COLS - str_len) / 2 ))" 434 │ [[ $# -ge 2 ]] && ch="${2:0:1}" || ch=" " 435 │ filler="" 436 │ for (( i = 0; i < filler_len; i++ )); do 437 │ filler="${filler}${ch}" 438 │ done 439 │ 440 │ printf "%s%s%s" "$filler" "$1" "$filler" 441 │ [[ $(( (TERM_COLS - str_len) % 2 )) -ne 0 ]] && printf "%s" "${ch}" 442 │ printf "\n" 443 │ 444 │ return 0 445 │ } 446 │ 447 │ check(){ ## check for entry 448 │ cd /var/www 449 │ for MD in $(find . -name '*.md' -print) 450 │ do 451 │ grep -Hc "$1" $MD |egrep -v '0$' 452 │ done 453 │ echo "${BY} $(find . -name "$1" -print)${N}" 454 │ cd - >/dev/null 455 │ } 456 │ 457 │ crn(){ ## connect to web server 458 │ event login 459 │ if [ -z $DISPLAY ] 460 │ then 461 │ ssh -q -X -tt crn "$*" 462 │ else 463 │ [ "$#" -gt 0 ] && TITLE="-T $*" 464 │ xfce4-terminal --tab --geometry=100x27 $TITLE --active-tab -x ssh -q -X -tt crn "$*" 465 │ fi 466 │ clear 467 │ } 468 │ 469 │ ct(){ ## Coffee timer or cooking timer 470 │ # Use: ct {time} 471 │ if [ "$#" -gt 0 ] 472 │ then 473 │ echo -n "${BG}Cooking timer $1${N} ⏳ " ;spinit sleep $1 474 │ else 475 │ # French press timer (default action) 476 │ echo -n "${BG}Making Coffee${N} ☕ " ;spinit sleep 4m 477 │ fi 478 │ if [ -z $DISPLAY ] 479 │ then 480 │ clear 481 │ if [ "$#" -gt 0 ] 482 │ then 483 │ echo "⏳${BR}Done${N}" 484 │ else 485 │ echo "☕${BR}Coffee ready${N}" 486 │ fi 487 │ bl 488 │ else 489 │ if [ "$#" -gt 0 ] 490 │ then 491 │ notify-send -u critical "⏳ Done!" 492 │ else 493 │ notify-send -u critical "☕ Coffee ready!" 494 │ fi 495 │ mpv ~/Music/sounds/chime.wav >/dev/null 2>&1 496 │ fi 497 │ } 498 │ 499 │ 500 │ days_until(){ ## display days until event 501 │ # 1. Convert target date (argument $1) to seconds since epoch 502 │ local target_epoch 503 │ target_epoch=$(date -d "$1" +%s) || return 1 504 │ 505 │ # 2. Get current time in seconds since epoch 506 │ local current_epoch 507 │ current_epoch=$(date +%s) 508 │ 509 │ # 3. Calculate difference in seconds 510 │ local diff_seconds=$(( target_epoch - current_epoch )) 511 │ 512 │ # 4. Convert seconds to days (86400 seconds in a day) 513 │ local diff_days=$(( diff_seconds / 86400 )) 514 │ 515 │ if [ "$diff_days" -lt 0 ]; then 516 │ echo "The date $1 has already passed ($(( -diff_days )) days ago)." 517 │ else 518 │ echo "${2} There are ${BR}$diff_days${N} days until ${SIT}$1${RIT}." 519 │ fi 520 │ } 521 │ 522 │ 523 │ 524 │ db(){ ## open a database 525 │ cd ~/db 526 │ CHOICE=$(\ls |fzf --ansi --reverse --color fg:-1,bg:-1,hl:46,fg+:40,bg+:233,hl+:46 --color prompt:166,border:46 --height 70% --border=sharp --prompt="➤ " --pointer="➤ " --marker="➤ ") 527 │ case $CHOICE in 528 │ *sqlite) sqlite3 $CHOICE 529 │ ;; 530 │ *) vd $CHOICE 531 │ ;; 532 │ esac 533 │ cd - 534 │ } 535 │ 536 │ display(){ ## show display settings 537 │ # Use: display (no options) 538 │ [ "$DEBUG" == 1 ] && set -x 539 │ if [ -z $DISPLAY ] 540 │ then 541 │ xfce4-terminal --color-table 542 │ echo "${BG}Display:${N} $(w|tail -1|awk '{print $3}') ${BC} $TERM${N} $(tput lines)r x $(tput cols)c" 543 │ else 544 │ xfce4-terminal --color-table 545 │ echo "${BG}Display: ${BY}$DISPLAY${N} ${BC}$TERM${N} $(tput lines)r x $(tput cols)c" 546 │ fi 547 │ line 548 │ } 549 │ 550 │ ul(){ ## Upload to server files 551 │ rsyncy "$@" ${DL} 552 │ play -q ~/Music/sounds/system/completion-success.oga 2>/dev/null 553 │ rm -i "$@" 554 │ } 555 │ 556 │ edir(){ ## emoji directory used in PS1 557 │ # Use: See $PS1 at top of this file 558 │ [ "$#" -ne 0 ] && grep -A 1 \^edir ~/.bashrc && return 559 │ case $PWD in # Order is important, stops on 1st match 560 │ *Archives*) echo -n "📦 ";; 561 │ *bin*) echo -n "🔧 ";; 562 │ *etc*) echo -n "⌨ ";; 563 │ *Documents*) echo -n "📃 ";; 564 │ *Downloads*) echo -n "🔽 ";; 565 │ *jots*) echo -n "📝 ";; 566 │ *Music*) echo -n "🎧 ";; 567 │ *pics*|*Pictures*) echo -n "📸 ";; 568 │ *tmp*|*Temp*) echo -n "🚽 ";; 569 │ *vids*|*Videos*) echo -n "🎬 ";; 570 │ *web*|*www*) echo -n "🕸 ";; 571 │ /home/mitch) echo -n "🏠 ";; 572 │ *) echo -n "📂 ";; 573 │ esac 574 │ } 575 │ 576 │ emoji(){ ## search and display emoji 577 │ # Use: emoji -h or --help for use 578 │ case $1 in 579 │ -s) # search 580 │ grep -i --color $2 ~/etc/emoji.txt 581 │ ;; 582 │ -r) # random 583 │ shuf -n 1 <~/etc/emoji.txt|cut -d' ' -f1 584 │ ;; 585 │ -R) # random 586 │ shuf -n 1 <~/etc/emoji.txt|cut -d' ' -f1| tr -d \\n 587 │ ;; 588 │ -d) # dump 589 │ for SMILE in $(cut -d' ' -f1 <~/etc/emoji.txt) 590 │ do 591 │ echo -n $SMILE 592 │ done 593 │ ;; 594 │ *) # help 595 │ fmt -s -w $(tput cols)<<END 596 │ ${BG}emoji${N} {option} 597 │ -s {text} # search 598 │ -r # random 599 │ -R # random, no new line 600 │ -d # dump 601 │ END 602 │ ;; 603 │ esac 604 │ } 605 │ 606 │ explain () { ## Use the explain API to explain commands - from the command line! 607 │ if [ "$#" -eq 0 ]; then 608 │ while read -p "Command: " cmd; do 609 │ curl -Gs "https://www.mankier.com/api/v2/explain/?cols="$(tput cols) --data-urlencode "q=$cmd" 610 │ done 611 │ echo "Bye!" 612 │ elif [ "$#" -eq 1 ]; then 613 │ curl -Gs "https://www.mankier.com/api/v2/explain/?cols="$(tput cols) --data-urlencode "q=$1" 614 │ else 615 │ echo "Usage" 616 │ echo "explain interactive mode." 617 │ echo "explain 'cmd -o | ...' one quoted command to explain it." 618 │ fi 619 │ # Update 26-03-2015. If using this command gives no output, see if running a simple fetch causes this error: 620 │ # $ curl https://www.mankier.com 621 │ # curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s). 622 │ # If so, try specifying a cipher in the curl commands: curl --ciphers ecdhe_ecdsa_aes_128_sha 623 │ } 624 │ 625 │ 626 │ extract(){ ## handy archive extraction 627 │ # Use: extract {file} 628 │ [ "$DEBUG" == 1 ] && set -x 629 │ if [ -f $1 ] 630 │ then 631 │ case $1 in 632 │ *.tar.bz2) tar xvjf $1 ;; 633 │ *.tar.gz) tar xvzf $1 ;; 634 │ *.bz2) bunzip2 $1 ;; 635 │ *.rar) unrar x $1 ;; 636 │ *.gz) gunzip $1 ;; 637 │ *.tar) tar xvf $1 ;; 638 │ *.tbz2) tar xvjf $1 ;; 639 │ *.tgz) tar xvzf $1 ;; 640 │ *.zip) unzip $1 ;; 641 │ *.Z) uncompress $1 ;; 642 │ *.7z) 7z x $1 ;; 643 │ *) echo "${BR}$1 ${N}cannot be extracted via >extract<" 644 │ file $1;; 645 │ esac 646 │ play -q ~/Music/sounds/system/dialog-information.oga 2>/dev/null 1>&2 647 │ else 648 │ echo "${BR}$1 $N is not a valid file" 649 │ fi 650 │ } 651 │ 652 │ fr() { ## fuzzy run 653 │ launchapp=$(IFS=':'; \ 654 │ for p in ${PATH}; \ 655 │ do find -L "${p}" -type f -executable -print 2> /dev/null; done \ 656 │ | fzf --header="Select application to launch:" \ 657 │ --exact \ 658 │ --height="50%" \ 659 │ --preview="(file -b {})" \ 660 │ --preview-window="down:wrap:25%") \ 661 │ && eval "${launchapp}" 662 │ } 663 │ 664 │ gmt(){ ## display GMT (for radio stuff) 665 │ 666 │ command -v tty-clock >/dev/null || sudo apt install tty-clock -yyq 667 │ xtitle "GMT Clock" 668 │ tty-clock -usxrB -C $(( ( RANDOM % 6 ) + 1 )) 669 │ } 670 │ 671 │ html(){ ## mark up code, etc... 672 │ # Use: html {file} 673 │ vim -f +"syn on" +"colorscheme termschool" +"set nonu" +"set foldenable!" +"set nospell" +"run! syntax/2html.vim" +"wq" +"q" $1 674 │ } 675 │ 676 │ hping(){ ## httping with favorite options 677 │ # Use: hping {name} (defaults to my site) 678 │ PINGHOST="$1" 679 │ httping ${PINGHOST:=crn.hopto.org} -c 10 -S -Y -Z -s --offset-yellow 370 --offset-red 380 -K 680 │ } 681 │ 682 │ large (){ ## find files larger than 800m 683 │ find . -type f -name "*.mp4" -size +800M -exec ls -lh {} \; | awk '{print $5, $9}' 684 │ } 685 │ 686 │ log(){ ## creates a basic log entry $LOG must be defined 687 │ # Use: log {entry} 688 │ [ "$DEBUG" == "1" ] && set -x 689 │ logger -i -t "$NAME" "$*" 690 │ } 691 │ 692 │ man(){ ## run mangl if DISPLAY is set 693 │ if [ -z $DISPLAY ] 694 │ then 695 │ /usr/bin/man $1 696 │ else 697 │ mangl $1 2>/dev/null 698 │ fi 699 │ } 700 │ 701 │ md2pdf(){ ## covert markdown to pdf 702 │ pandoc ${1%.md}.md -o ${1%.md}.html 703 │ cat ${1%.md}.html |htmldoc --cont --headfootsize 8.0 --linkcolor blue --linkstyle plain --format pdf14 - > ${1%.md}.pdf && gio trash ${1%.md}.html 704 │ } 705 │ 706 │ more(){ ## updated to set title bar 707 │ # Use: more {file} 708 │ xtitle "more $*" 709 │ EXT="${1##*.}" 710 │ case $EXT in 711 │ epub|fb2|mobi) # books 712 │ /home/mitch/.local/bin/epy $1 713 │ ;; 714 │ md) # markdown 715 │ glow -t $1 716 │ ;; 717 │ csv|tsv) # tab/csv separated 718 │ cat $1 |pspg --${EXT} --style=6 719 │ ;; 720 │ json|xlsx|xls|sqlite) # sqlite3 721 │ vd $1 722 │ ;; 723 │ *) # default 724 │ bat $1 725 │ ;; 726 │ esac 727 │ } 728 │ 729 │ mp(){ ## media player front end 730 │ FZF_DEFAULT_OPTS="--ansi " 731 │ # Use: mp {optional file} 732 │ [ "$1" == "-d" ] && cd ~/Downloads # jump to download directory 733 │ [ -z $DISPLAY ] || WINDOW=$(xdotool getactivewindow 2>/dev/null) # get window ID 734 │ clear 735 │ if [ -f "$1" ] # if you give it a file run it, else display a list 736 │ then 737 │ CHOICE="$1" 738 │ else 739 │ xtitle "mp: Name sort" 740 │ CHOICE=$(lm|fzf --reverse --ansi --color fg:-1,bg:-1,hl:46,fg+:40,bg+:233,hl+:46 --color prompt:166,border:46 --height 70% --border=rounded --prompt="➤ " --pointer="➤ " --marker="➤ ") 741 │ fi 742 │ EXT="${CHOICE##*.}" 743 │ [ "$EXT" == "mp3" ] && FILE=$(echo $CHOICE|cut -d ' ' -f5) 744 │ [ "$EXT" == "mp4" ] && FILE=$(echo $CHOICE|cut -d ' ' -f4) 745 │ if [ ! -z $FILE ] 746 │ then 747 │ if [ ! -z $DISPLAY ] 748 │ then 749 │ xtitle "$FILE" 750 │ echo -n "Playing: $FILE " 751 │ xdotool windowminimize $WINDOW 752 │ xfconf-query --channel=xfwm4 --property=/general/use_compositing --type=bool --toggle 753 │ spinit vlc --play-and-exit $FILE 1>&2 2>/dev/null 754 │ xdotool windowactivate $WINDOW 755 │ xfconf-query --channel=xfwm4 --property=/general/use_compositing --type=bool --toggle 756 │ if [ -f $FILE -a "$(pwd)" == "/home/mitch/Downloads" ] || [ "$(pwd)" == "/var/hold/Downloads" ] 757 │ then 758 │ clear 759 │ read -p "${BR}Remove:${BY} ${FILE}?${N} " -n 1 DEL 760 │ if [ "$DEL" == "y" ] 761 │ then 762 │ rm $FILE 763 │ fi 764 │ bl 765 │ if [ -f $FILE ] 766 │ then 767 │ read -p "${BR}Upload:${BY} ${FILE}?${N} " -n 1 DEL 768 │ [ "$DEL" == "y" ] && ul $FILE 769 │ fi 770 │ bl 771 │ if [ -f $FILE ] 772 │ then 773 │ bl 774 │ read -p "${BY}mv${N} $FILE to ~/Temp? " -n 1 MV 775 │ [ "$MV" == "y" ] && mv $FILE ~/Temp 776 │ fi 777 │ fi 778 │ if [ "$1" == "-n" ] 779 │ then 780 │ clear 781 │ [[ $(\ls -A *.mp? 2>/dev/null) ]] && llm || echo "No files" 782 │ else 783 │ clear 784 │ [[ $(\ls -A *.mp? 2>/dev/null) ]] && llm -t || echo "No files" 785 │ fi 786 │ else 787 │ echo "$FILE not played, no DISPLAY" 788 │ fi 789 │ fi 790 │ } 791 │ 792 │ pause(){ 793 │ [ "$DEBUG" == "1" ] && set -x; 794 │ [ "$1" == "-nt" ] && TMOUT="" && shift; 795 │ echo "$BY"; 796 │ if [ $# -gt 0 ]; then 797 │ read -t $1 -r -p "${C}Hit any key (${BY}$1${C} second timeout)${N}" -n 1 FOO; 798 │ else 799 │ read -r -p "${C}Hit any key${N}" -n 1 FOO; 800 │ fi; 801 │ bl 802 │ } 803 │ 804 │ r(){ # r run it! 805 │ # Use: r {optional pattern: p*} 806 │ if [ $(\ls -F|grep -c '\*') -lt 1 ] 807 │ then 808 │ echo "${BY}Nothing to do${N}" 809 │ else 810 │ CHOICE=$(\ls -F "$@" | grep '*$' |tr -d '*' |fzf --ansi --reverse --color fg:-1,bg:-1,hl:46,fg+:40,bg+:233,hl+:46 --color prompt:166,border:46 --height 70% --border=sharp --prompt="➤ " --pointer="➤ " --marker="➤ ") 811 │ if [ ! -z "$CHOICE" ] 812 │ then 813 │ tldr $CHOICE 2> /dev/null | tail -n +3 814 │ read -p "${BG}${CHOICE} ${N}" ARGS 815 │ ./${CHOICE} $ARGS 816 │ fi 817 │ fi 818 │ } 819 │ 820 │ rcf() { ## Function to set random background and foreground colors with contrast # Use: rcf "string" 821 │ 822 │ # Generate random 1-6 for fg/bg to ensure contrast (avoiding 0/7/8) 823 │ local fg=$(( (RANDOM % 6) + 1 )) 824 │ local bg=$(( (RANDOM % 6) + 1 )) 825 │ 826 │ # Ensure background is not too similar to foreground 827 │ while [ $fg -eq $bg ]; do 828 │ bg=$(( (RANDOM % 6) + 1 )) 829 │ done 830 │ 831 │ # Apply colors and print 832 │ tput setaf $fg 833 │ tput setab $bg 834 │ tput bold # Make text bold for better readability 835 │ echo -n " $1 " 836 │ tput sgr0 # Reset colors 837 │ echo "" 838 │ } 839 │ 840 │ recover(){ ## vim recover from backup dir 841 │ if [ -f "$1" ] 842 │ then 843 │ FILE="$(pwd)/$1" 844 │ cd ~/vim/backup 845 │ CHOICE=$(\ls -a |fzf -m --ansi --color fg:-1,bg:-1,hl:46,fg+:40,bg+:233,hl+:46 --color prompt:166,border:46 --height 70% --border=sharp --prompt="➤ " --pointer="➤ " --marker="➤ " --preview '(highlight -O ansi {} || bat -p {}) 2> /dev/null | head -500') 846 │ vimdiff "$FILE" "$CHOICE" 847 │ else 848 │ echo "recover {file}" 849 │ echo " 850 │ vimdiff commands 851 │ 852 │ ]c : - next difference 853 │ [c : - previous difference 854 │ do - diff obtain 855 │ dp - diff put 856 │ zo - open folded text 857 │ zc - close folded text 858 │ :diffupdate - re-scan the files for differences 859 │ :set mouse=a - use mouse click to switch windows 860 │ CTRL-W = - resize windows the same 861 │ CTRL-W w - switch window 862 │ " 863 │ fi 864 │ cd ${OLDDIR} 865 │ } 866 │ 867 │ rs(){ ## restart shell with option to edit .bashrc 868 │ # Use: rs (if anything is passed it will edit .bashrc file 1st) 869 │ THEME="zenburn" # bat --list-themes 870 │ if [ $# -gt 0 ] 871 │ then 872 │ play -q ~/Music/sounds/system/message-new-instant.oga 2>/dev/null 873 │ vim ~/.bashrc 874 │ sed -i -e "3s/.*/# Updated....: $(date)/" ~/.bashrc 875 │ # bashrc 876 │ log "Updated ~/.bashrc" 877 │ bat --color=always --theme $THEME ~/.bashrc | aha -b -w -t "~/.bashrc" >/var/www/unix/bashrc.html 878 │ cp ~/.bashrc /var/www/unix/bashrc 879 │ 880 │ # vimrc - Added to make sure the Web versions were up to date. 881 │ sed -i -e "3s/.*/\" Updated....: $(date)/" ~/.vimrc 882 │ bat --color=always --theme $THEME ~/.vimrc | aha -b -w -t "~/.vimrc" >/var/www/unix/vimrc.html 883 │ cp ~/.vimrc /var/www/unix/vimrc 884 │ 885 │ log "Restart: $$" 886 │ exec bash 887 │ else 888 │ log "Restart: $$" 889 │ reset; exec bash 890 │ fi 891 │ } 892 │ 893 │ rss(){ ## quick rss url reader 894 │ # Use: rss {URL} {Count, defaults to 10} 895 │ [ "$#" -eq 2 ] && COUNT=$2 || COUNT=10 896 │ lynx -stdin <<RSSEND 897 │ <p>rss "$1" 898 │ </p> 899 │ 900 │ $(rsstail --nofail --time-format '%r %m/%d/%Y' --initial $COUNT -e 1 --format '[{title}]({link}) {updated:>10} \n' "$1" |pandoc -t html) 901 │ 902 │ RSSEND 903 │ } 904 │ 905 │ scale(){ ## change to 640x480 906 │ (xterm -geometry 140x4+0+900 -hold -e ~/bin/scale $1 &) 907 │ } 908 │ 909 │ sconky(){ ## re-start conky 910 │ # Use: sconky (if anything is passed it will edit config file 1st) 911 │ pkill conky 912 │ spinit sleep 3 913 │ (conky -d -c ~/.conkyrc) 914 │ /home/mitch/bin/now-clocking-main/start.sh 2>&1 915 │ 916 │ } 917 │ 918 │ tab() { ## run command in new tab 919 │ xfce4-terminal --tab --geometry=100x27 -T "$*" --active-tab -x "$*" 920 │ } 921 │ 922 │ tunes(){ ## play my music 923 │ SDIR=$(pwd) 924 │ cd ~/Music/gospel/kjv 925 │ \rm *mp3 926 │ cd ~/Music/kjv-verses 927 │ for VERSE in $(\ls |shuf -n 20) 928 │ do 929 │ cp $VERSE ~/Music/gospel/kjv 930 │ done 931 │ cd ~/Music && find gospel/ -name '*.mp3' >tunes.m3u 932 │ xtitle "Playing music" 933 │ xfce4-terminal --tab --geometry=100x27 --title="Tunes" --active-tab -x nvlc -Z tunes.m3u 934 │ cd $SDIR 935 │ clear 936 │ } 937 │ 938 │ xtitle(){ ## set window title 939 │ # Use: xtitle "Text to display" 940 │ printf "\033]0;%s\007" "${*}🌀${HOSTNAME}" 941 │ } 942 │ 943 │ 944 │ # Ending 945 │ # ====== 946 │ clear 947 │ if [ "$LOGNAME" == "mitch" ] 948 │ then 949 │ play -q ~/Music/system/outcome-success.oga 2>/dev/null 950 │ uptime 951 │ status 952 │ today -s 953 │ days_until "April 22" "🚙" 954 │ days_until "May 4" "💵" 955 │ days_until "June 12" "👣" 956 │ else 957 │ log "Switching to root" 958 │ echo "${BY}sudo: ${BR}switched to root$N" 959 │ HISTFILE=/.root.hist # keeps it out of mine 960 │ TMOUT=600 # Close terminal after 10 minutes of inactivity 961 │ echo "Window timeout in: ${BY}$TMOUT seconds${N}" 962 │ export PS1='ES:$(success_indicator) $(printf "\033]0;🌀\h:\w \007")L:${BY}$SHLVL${N} J:${BY}\j${N} ${BY}[\u🌀\h] $(edir)\w${N}\n${BR}#${N} ' 963 │ fi 964 │ 965 │ [ -f ~/.fzf.bash ] && source ~/.fzf.bash 966 │ 967 │ 968 │ # ServerHub completion 969 │ if command -v serverhub &> /dev/null; then 970 │ source <(serverhub completion bash 2>/dev/null || true) 971 │ fi ───────┴────────────────────────────────────────────────────────────────────────