bashrc/.bashrc.d/11-functions.bashrc

716 lines
24 KiB
Plaintext
Raw Normal View History

2023-03-18 12:49:08 +01:00
#!/usr/bin/env bash
# executed by bash(1) for non-login shells.
# ==============================
# FUNCTIONS
# ==============================
# ==============================
# System
# ==============================
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# pass declared functions to sudo, /!\ aliases in the function will not work
sudof() {
Help() {
cat <<- HEREDOC
Pass declared functions as command to sudo bash.
Syntax: sudof [-h] <functionName> [<options/arguments>]
options:
-h Print this Help.
HEREDOC
}
while getopts ":h" option; do
case $option in
h) Help; return 0 ;;
\?) echo -e "Unknown option: -$OPTARG \n" >&2; Help; return 1;;
: ) echo -e "Missing argument for -$OPTARG \n" >&2; Help; return 1;;
* ) echo -e "Unimplemented option: -$option \n" >&2; Help; return 1;;
esac
done
local TMPFUNC=$(declare -f "$1")
local TMPCMD=${@:1}
sudo bash -c "$TMPFUNC; $TMPCMD"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Pretty print dependencies from a package with dpkg
dpkg-debdep() {
dpkg --info "$1" | \
awk 'BEGIN{print "Depends:"} \
/Depends: / { gsub("Depends: ", ""); \
n=split($0,deps,","); \
for(i=1;i<=n;i++) print deps[i] \
}'
}
# ==============================
# Terminal
# ==============================
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# set of functions for marks/jump, MARKPATH created/exported in 01.env.bashrc
mark() { ln -s "$(pwd)" "$MARKPATH/$1"; }
unmark() { rm -i "$MARKPATH/$1"; }
marks() { ls -l "$MARKPATH" | sed 's/ / /g' | cut -d' ' -f9- | sed 's/ -/\t-/g' && echo; }
jump() { cd -P "$MARKPATH/$1" 2>/dev/null || echo "No such mark: $1"; }
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# pipe to hl only if you are in a tty and the output is not piped or redirected
if command -v hl 1> /dev/null; then
hlauto() {
if [ -t 1 ]; then
hl "$1"
else
cat -
fi
}
fi
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# full page of \n for the clear alias
pgdown() {
printf '\n%.0s' $(eval echo {1..$(( $(tput lines) - 1 ))})
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# clear teminal and TMUX history and get to the bottom line
c() {
echo -en "\ec"; pgdown
if [[ -n $TMUX_PANE ]]; then
tmux clear-history -t "$TMUX_PANE"
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# shortcut for tmux to open a new default session with a name or attach if it exist
# an alias tmuxs exist too for ssh sessions
if command -v tmux 1> /dev/null; then
tmuxa() {
systemd-run -q --scope --user tmux new-session -A -s default "$@"
exit
}
fi
# ==============================
# Utils
# ==============================
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# mkdir with sub-dirs and change of pwd
md() { mkdir -pv "$1" && cd "$1"; }
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# list almost all services units (except user disabled) with state color
lservices() {
Help() {
cat <<- HEREDOC
List all Systemd services units.
Simplified and colorful.
Syntax: lservices [-h] [-x] [<username>]
Output: ServiceName UID STATE DESCRIPTION
options:
-h Print this Help.
-x Copy the list to Clipboard with xclip.
-p Disable the pager feature.
<username> [root] display --system services,
[other] display --user services,
[empty] default to current user.
HEREDOC
}
local OPTIND=0
while getopts ":hxp" option; do
case $option in
h) Help; return 0 ;;
x) local _XCLIP=1;;
p) local _NOPAGER=1;;
\?) echo -e "Unknown option: -$OPTARG \n" >&2; Help; return 1;;
: ) echo -e "Missing argument for -$OPTARG \n" >&2; Help; return 1;;
* ) echo -e "Unimplemented option: -$option \n" >&2; Help; return 1;;
esac
done
shift $((OPTIND-1))
if [[ -z $1 ]]; then
local _UID=$(id -u)
else
local _UID=$(id -u $1)
fi
if [[ "$_UID" == "0" ]]; then
local _OUT=$(sudo systemctl list-units --system -q --plain --full --no-pager -t service)
elif [[ "$_UID" == "$(id -u)" ]]; then
local _OUT=$(systemctl list-units --user -q --plain --full --no-pager -t service)
else
local _OUT=$(sudo machinectl -q shell --uid="$_UID" .host /usr/bin/systemctl list-units --user -q --plain --full --no-pager -t service)
fi
if [[ $_XCLIP == 1 ]]; then
echo -e "${_OUT}" | xclip -selection clipboard
fi
local _OUT=$(echo "$_OUT" | awk -v uid=$_UID ' \
BEGIN {
red = "\033[1;31m"
green = "\033[1;32m"
yellow = "\033[1;33m"
blue = "\033[1;36m"
reset = "\033[0m"
map["running"] = green
map["exited"] = yellow
map["failed"] = red
}
match($0,/^(.*)\.service(\s*)loaded\s[a-z]+\s([a-z]+)(\s.*)$/,a) {
status = a[3]
if ( status in map )
$0 = blue a[1] a[2] reset " " uid " " map[status] status reset a[4]
else
$0 = blue a[1] a[2] reset " " uid " " a[3] a[4]
}
{ print } '
)
if [[ $_NOPAGER == 1 ]]; then
echo -e "${_OUT}"
else
echo -e "${_OUT}" | less --ignore-case --LONG-PROMPT --mouse --RAW-CONTROL-CHARS --tilde --use-color --quit-if-one-screen
fi
if [[ $_XCLIP == 1 ]]; then
echo "List copied in the system clipboard!"
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# bat/cat-like with no comments
if command -v bat 1> /dev/null; then
batl() {
bat -pp --color always "$@" \
| sed -E -e '1b;/^(\x1B\[[0-9;]+m\s*\x1B\[[0-9;]+m\x1B\[[0-9;]+m)?(\s+)?(\x1B\[[0-9;]+m)?(#|\")/d' \
| bat --decorations never --pager "less --ignore-case --status-column --line-numbers --quiet --tilde --use-color --quit-if-one-screen --RAW-CONTROL-CHARS"
}
fi
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# custom alternative to ls that pipe to fzf-tmux or fzf
lf() {
Help() {
cat <<- HEREDOC
A custom alternative to ls that pipe to fzf-tmux or fzf
Accept only the first path submitted (Default=.)
Syntax: lf [-h] [-a] [-e] [-o] [-t -l level] [<path>]
options:
-h Print this Help.
-a Display hidden files
-e Sort by extension
-o Sort by oldest
-t Tree mode
-l num Tree level, default=2
HEREDOC
}
local _type="list"
local _filter="visible"
local _by="name"
local _lvl=""
local _fzf_opt="--preview-window down:5:wrap"
local OPTIND=0
while getopts ":haeotl:" option; do
case $option in
h) Help; return 0 ;;
a) local _all="-a"
local _filter="all";;
e) local _sort="--sort=extension"
local _by="ext" ;;
o) local _sort="--sort=oldest"
local _by="oldest" ;;
t) local _tree="-T"
local _type="tree"
local _fzf_opt="--keep-right --preview-window down:2:wrap"
local _lvl=", with 2 level," ;;
l) local _level="-L ${OPTARG}"
local _lvl=", with ${OPTARG} level," ;;
\?) echo -e "Unknown option: -$OPTARG \n" >&2; Help; return 1;;
: ) echo -e "Missing argument for -$OPTARG \n" >&2; Help; return 1;;
* ) echo -e "Unimplemented option: -$option \n" >&2; Help; return 1;;
esac
done
shift $((OPTIND-1))
if [[ -f "/usr/bin/tmux" || -f "/usr/local/bin/tmux" ]]; then
local _fzfCmd="fzf-tmux -p 95%,75%"
else
local _fzfCmd="fzf"
fi
if [ -z "$1" ]; then
local _location="$(realpath -sq "$PWD" 2>&1)"
elif [ -z "$2" ]; then
local _location="$(realpath -sq "$1" 2>&1)"
else
echo "Error: Invalid number of paths"
Help
return 0
fi
local _localizer="awk -v loc=\"$_location/\" '{print \"\\\"\" loc \$0 \"\\\"\"}'"
local _oneliner="sed -E -e 's/\s->\s.+//g' \
| awk '{\$1=\$2=\$3=\$4=\$5=\$6=\$7=\"\"; \$0=\$0; \$1=\$1; print \$0}' \
| sed -E -e 's/^[^[:digit:][:alpha:]_.]*\s//g' \
| awk -v loc=\"$_location/\" '{print \"\\\"\" loc \$0 \"\\\"\"}' \
| xargs -d \"\n\""
if [[ "$_type" == "tree" ]]; then
local _localizer="awk '{print \"\\\"\" \$0 \"\\\"\"}'"
local _oneliner="cat"
fi
exa -bghHl $_all $_sort $_tree $_level --icons --git --color always --group-directories-first --time-style=long-iso "$_location" 2>&1 \
| ${_fzfCmd} -p 95%,75% --multi --reverse --ansi --tabstop 2 --header-lines 1 \
--prompt "A $_type$_lvl of $_filter elements sorted by $_by in \"$_location\" > " \
$_fzf_opt --bind ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all,ctrl-p:toggle-preview \
--preview "for line in {+}; do echo \"\$line\"; done \
| sed -E -e 's/\s->\s.+//g' \
| awk '{\$1=\$2=\$3=\$4=\$5=\$6=\$7=\"\"; \$0=\$0; \$1=\$1; print \$0}' \
| sed -E -e 's/^[^[:digit:][:alpha:]_.]*\s//g' \
| $_localizer \
| xargs -d \"\n\"" \
| eval "$_oneliner"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# find file/symlinks or directories with fd and fzf, use a regex pattern and an optionnal location
fdf() {
local array=( fd exa fzf bat )
for cmd in "${array[@]}"; do
if [[ -z $(command -v $cmd) ]]; then
echo 'function requirements: $cmd could not be found: sudo apt install fd-find exa fzf bat'
return 0
fi
done
Help() {
cat <<- HEREDOC
Filesystem search shortcuts with fd, fzf bat and exa
Syntax: fdf [-h] [-d] [-p] [-e] "<regex_query>" [<location>]
options:
-h Print this Help.
-d search directories only (defaut to files & symlinks)
-p preview in fzf (bat for files and exa tree for dirs)
-e output results with exa
HEREDOC
}
local _fdfindType="-tf -tl"
if [[ -f "/usr/bin/tmux" || -f "/usr/local/bin/tmux" ]]; then
local _fzfCmd="fzf-tmux"
else
local _fzfCmd="fzf"
fi
local _previewCdm="bat --style=numbers --color=always --line-range :150 {}"
local _xargs="cat"
local OPTIND=0
while getopts ":hdpe" option; do
case $option in
h) Help; return 0 ;;
d) local _fdfindType="-td"
local _exaType="-d"
local _fzfHeaderType="dir"
local _previewCdm="exa -bhlaTL 2 --icons --color always --group-directories-first --no-permissions --time-style=iso {}" ;;
p) local _fzfCmd="fzf"
local _preview=$_previewCdm ;;
e) local _xargs="xargs -r exa -abghHl --icons --color always --group-directories-first --time-style=long-iso" ;;
\?) echo -e "Unknown option: -$OPTARG \n" >&2; Help; return 1;;
: ) echo -e "Missing argument for -$OPTARG \n" >&2; Help; return 1;;
* ) echo -e "Unimplemented option: -$option \n" >&2; Help; return 1;;
esac
done
shift $((OPTIND-1))
if [ -z "$1" ]; then
echo "Error: fdf needs a <regex_query>"
Help
return 0
fi
if [ -z "$2" ]; then
local _searchPath="$(realpath -sq "$PWD" 2>&1)"
else
local _searchPath="$(realpath -sq "$2" 2>&1)"
fi
fdfind -0aH $_fdfindType ^$1\$ "$_searchPath" | xargs -r -0 exa $_exaType --colour=always \
| $_fzfCmd -m --reverse --ansi --keep-right --bind ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all --header "^$1\$ $_fzfHeaderType in \"$_searchPath\"" --preview "$_preview" | eval "$_xargs"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# better listing for all tcp/udp sockets
ssfull() {
if [[ -f "/usr/bin/tmux" || -f "/usr/local/bin/tmux" ]]; then
local _fzfCmd="fzf-tmux"
else
local _fzfCmd="fzf"
fi
ss -Haptun --cgroup 2>&1 \
| awk '{gsub(/cgroup:/,"- - cgroup:",$7);if($7 =="")print $0" - - -";else print $0;}' \
| awk '{
gsub(/,fd=.+,pid=/,",",$7);gsub(/users:|\(|\)|,fd=[0-9]+/,"",$7);gsub(/,pid=/," ",$7);
gsub(/.+\/|cgroup:/,"",$8);
gsub(/.+\/|cgroup:/,"",$9);
if(match($5, /^.+%[^\]]+:.+$/))localip = gensub(/^(.*[0-9\]*])%.+:[0-9*]{1,5}$/,"\\1","g",$5);else localip = gensub(/^(.*):[0-9*]{1,5}$/,"\\1","g",$5);
if(match($5, /^.+%[^\]]+:.+$/))localindex = gensub(/^.+%([^\]]+):.+$/,"\\1","g",$5);else localindex = "-";
localport = gensub(/^.*:([^:]*)$/,"\\1","g",$5);
if(match($6, /^.+%[^\]]+:.+$/))peerip = gensub(/^(.*[0-9\]*])%.+:[0-9*]{1,5}$/,"\\1","g",$6);else peerip = gensub(/^(.*):[0-9*]{1,5}$/,"\\1","g",$6);
if(match($6, /^.+%[^\]]+:.+$/))peerindex = gensub(/^.+%([^\]]+):.+$/,"\\1","g",$6);else peerindex = "-";
peerport = gensub(/^.*:([^:]*)$/,"\\1","g",$6);
stategroup = "";
if(match($2, /^ESTAB$/))stategroup = "1-ESTABL";
if(match($2, /^SYN-SENT$/))stategroup = "1-ESTABL";
if(match($2, /^SYN-RECV$/))stategroup = "1-ESTABL";
if(match($2, /^FIN-WAIT-1$/))stategroup = "2-CLOSIN";
if(match($2, /^FIN-WAIT-2$/))stategroup = "2-CLOSIN";
if(match($2, /^CLOSE-WAIT$/))stategroup = "2-CLOSIN";
if(match($2, /^LAST-ACK$/))stategroup = "2-CLOSIN";
if(match($2, /^CLOSING$/))stategroup = "2-CLOSIN";
if(match($2, /^TIME-WAIT$/))stategroup = "3-WAITIN";
if(match($2, /^LISTEN$/))stategroup = "0-LISTEN";
if(match($2, /^UNCONN$/))stategroup = "0-LISTEN";
if(stategroup =="")stategroup = "-";
if($1 =="tcp" || $1 == "udp")print stategroup,$1,localip,localindex,localport,peerip,peerindex,peerport,$7,$8,$9;
}' \
| sort -k1,1 -k3,3 -k4,4 -k6,6n \
| awk 'BEGIN{print "StateGroup Protocol LocalAddr LocalIndex LocalPort PeerAddr PeerIndex PeerPort Process PID Cgroup"}1' \
| column -t \
| $_fzfCmd --multi --reverse --ansi --keep-right --tabstop 2 --header-lines 1 --prompt "List of all tcp/udp sockets > " --bind ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# better listing for listening tcp/udp sockets
sslisten() {
if [[ -f "/usr/bin/tmux" || -f "/usr/local/bin/tmux" ]]; then
local _fzfCmd="fzf-tmux"
else
local _fzfCmd="fzf"
fi
ss -Hlptun --cgroup 2>&1 \
| awk '{gsub(/cgroup:/,"- - cgroup:",$7);if($7 =="")print $0" - - -";else print $0;}' \
| awk '{
gsub(/,fd=.+,pid=/,",",$7);gsub(/users:|\(|\)|,fd=[0-9]+/,"",$7);gsub(/,pid=/," ",$7);
gsub(/.+\/|cgroup:/,"",$8);
gsub(/.+\/|cgroup:/,"",$9);
if(match($5, /^.+%[^\]]+:.+$/))localip = gensub(/^(.*[0-9\]*])%.+:[0-9*]{1,5}$/,"\\1","g",$5);else localip = gensub(/^(.*):[0-9*]{1,5}$/,"\\1","g",$5);
if(match($5, /^.+%[^\]]+:.+$/))localindex = gensub(/^.+%([^\]]+):.+$/,"\\1","g",$5);else localindex = "-";
localport = gensub(/^.*:([^:]*)$/,"\\1","g",$5);
if(match($6, /^.+%[^\]]+:.+$/))peerip = gensub(/^(.*[0-9\]*])%.+:[0-9*]{1,5}$/,"\\1","g",$6);else peerip = gensub(/^(.*):[0-9*]{1,5}$/,"\\1","g",$6);
if(match($6, /^.+%[^\]]+:.+$/))peerindex = gensub(/^.+%([^\]]+):.+$/,"\\1","g",$6);else peerindex = "-";
peerport = gensub(/^.*:([^:]*)$/,"\\1","g",$6);
stategroup = "";
if(match($2, /^LISTEN$/))stategroup = "LISTENING";
if(match($2, /^UNCONN$/))stategroup = "LISTENING";
if(stategroup =="")stategroup = "-";
if($1 =="tcp" || $1 == "udp")print stategroup,$1,localip,localindex,localport,peerip,peerindex,peerport,$7,$8,$9;
}' \
| sort -k1,1 -k3,3 -k4,4 -k6,6n \
| awk 'BEGIN{print "StateGroup Protocol LocalAddr LocalIndex LocalPort PeerAddr PeerIndex PeerPort Process PID Cgroup"}1' \
| column -t \
| $_fzfCmd --multi --reverse --ansi --keep-right --tabstop 2 --header-lines 1 --prompt "List of LISTENING tcp/udp sockets > " --bind ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all
}
# ==============================
# New commands or external programs
# ==============================
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# set shell working directory after leaving Vifm
if command -v vifmrun 1> /dev/null; then
vfcd() {
local dst="$(command vifmrun --choose-dir - "$@")"
if [ -z "$dst" ]; then
echo 'Directory picking cancelled/failed'
return 1
fi
cd "$dst"
}
fi
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# simple archive extraction of all kinds, get dep with "sudo apt install tar bzip2 unrar gzip unzip 7zip xz-utils innoextract cabextract"
extract() {
Help() {
cat <<- HEREDOC
Archive extraction simplified.
Syntax: extract [-h] <path/file_name>.<zip|rar|bz2|gz|tar|tbz2|tgz|Z|7z|xz|ex|tar.bz2|tar.gz|tar.xz>
extract <path/file_name_1.ext> [path/file_name_2.ext] [path/file_name_3.ext]
options:
-h Print this Help.
HEREDOC
}
while getopts ":h" option; do
case $option in
h) Help; return 0 ;;
\?) echo -e "Unknown option: -$OPTARG \n" >&2; Help; return 1;;
: ) echo -e "Missing argument for -$OPTARG \n" >&2; Help; return 1;;
* ) echo -e "Unimplemented option: -$option \n" >&2; Help; return 1;;
esac
done
array=( tar unlzma bunzip2 unrar gunzip unzip uncompress 7z unxz innoextract cabextract )
for cmd in "${array[@]}"; do
if [[ -z $(command -v "$cmd") ]]; then
echo "Requirements: at least $cmd could not be found:"
echo "sudo apt install tar bzip2 unrar gzip unzip 7zip xz-utils innoextract cabextract"
return 0
fi
done
for n in "$@"
do
if [[ -f "$n" ]] ; then
case "${n%,}" in
*.tar.bz2|*.tar.gz|*.tar.xz|*.tbz2|*.tgz|*.txz|*.tar)
tar xvf "$n" ;;
*.lzma) unlzma ./"$n" ;;
*.bz2) bunzip2 ./"$n" ;;
*.rar) unrar x -ad ./"$n" ;;
*.gz) gunzip ./"$n" ;;
*.zip) unzip ./"$n" ;;
*.z) uncompress ./"$n" ;;
*.7z|*.arj|*.cab|*.chm|*.deb|*.dmg|*.iso|*.lzh|*.msi|*.rpm|*.udf|*.wim|*.xar)
7z x ./"$n" ;;
*.xz) unxz ./"$n" ;;
*gog*.exe|*gog*.sh)
innoextract -es -c1 -p1 ./"$n" ;;
*.exe) cabextract ./"$n" ;;
*) echo "extract: '$n' - unknown archive method"; return 1;;
esac
else
echo "'$n' - file does not exist"
return 1
fi
done
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Command execution notifier
boop() {
Help() {
cat <<- HEREDOC
Command execution notifier.
- In front of a command: notification + sound + NTFY (env: NTFYBOOPSURL, NTFYBOOPSTOKEN)
(It send the command name and 1st arg, exec time and exit code)
- At the end of a chain: notification + sound
Syntax: Pre command: boop [-h] [sudo] <some command> | boop <some command>; boop <some command>
Post command: <some command>; boop
options:
-h Print this Help.
HEREDOC
}
while getopts ":h" option; do
case $option in
h) Help; return 0 ;;
\?) echo -e "Unknown option: -$OPTARG \n" >&2; Help; return 1;;
: ) echo -e "Missing argument for -$OPTARG \n" >&2; Help; return 1;;
* ) echo -e "Unimplemented option: -$option \n" >&2; Help; return 1;;
esac
done
local STATUS="$?"
local ARRAY1=( /usr/bin/time play dunstify )
local ARRAY2=( /usr/bin/time curl )
for cmd in "${ARRAY2[@]}"; do
if [[ -z $(command -v "$cmd") ]]; then
echo "boop function requirements: command $cmd could not be found"
return 1
fi
done
if [[ -z "$1" ]]; then
for cmd in "${ARRAY1[@]}"; do
if [[ -z $(command -v "$cmd") ]]; then
echo "boop function requirements: command $cmd could not be found"
return "$STATUS"
fi
done
if [[ "$STATUS" == '0' ]]; then
dunstify -a NTFY -u normal -i dialog-information "Commande terminée avec SUCCÉE ✅ !"
play -q -n synth pl G2 pl B2 pl D3 pl B3 pl D4 pl D4 delay 0 .05 .1 .15 .2 .25 remix - fade 0 2 .1 norm -1
else
dunstify -a NTFY -u critical -i dialog-error "Commande terminée avec une ERREUR ⚠️ !" "Exit code : $STATUS"
play -q -n synth 3 sin 960 synth 3 sin fmod 1920 fade l 0 3 2.8 trim 0 1 repeat 2 norm -1
fi
return "$STATUS"
else
local FILE=$(mktemp --suffix ".time")
boop2ntfy() {
local TIME=$(awk 'NR==1{print $1}' "$FILE")
local STATUS=$(awk 'NR==1{print $2}' "$FILE")
if [[ -z $(awk 'NR==1{print $4}' "$FILE") ]]; then
local CMDBEGIN=$(awk 'NR==1{print $3}' "$FILE")
else
local CMDBEGIN="$(awk 'NR==1{print $3}' "$FILE") $(awk 'NR==1{print $4}' "$FILE")"
fi
local HOSTNAME=$(hostname)
local URL="$NTFYBOOPSURL"
local TOKEN="$NTFYBOOPSTOKEN"
if [[ "$STATUS" == '0' ]]; then
if command -v dunstify 1> /dev/null; then
dunstify -a NTFY -u normal -i dialog-information "Commande terminée avec SUCCÉE ✅ !" "Durée : $TIME - Commande : $CMDBEGIN"
fi
if command -v play 1> /dev/null; then
play -q -n synth pl G2 pl B2 pl D3 pl B3 pl D4 pl D4 delay 0 .05 .1 .15 .2 .25 remix - fade 0 2 .1 norm -1
fi
curl --max-time 25 -s -S -H "Authorization: Bearer ${TOKEN}" -H "X-Title: Hôte : $HOSTNAME" -H tag:tada -d "La commande \"$CMDBEGIN\" s'est terminée avec Succès ! (Durée : $TIME)" "$URL" &> /dev/null
else
if command -v dunstify 1> /dev/null; then
dunstify -a NTFY -u critical -i dialog-error "Commande terminée avec une ERREUR ⚠️ !" "Durée : $TIME - Exit code : $STATUS - Commande : $CMDBEGIN"
fi
if command -v play 1> /dev/null; then
play -q -n synth 3 sin 960 synth 3 sin fmod 1920 fade l 0 3 2.8 trim 0 1 repeat 2 norm -1
fi
curl --max-time 25 -s -S -H "Authorization: Bearer ${TOKEN}" -H "X-Title: Hôte : $HOSTNAME" -H "X-Priority: 4" -H tag:warning -d "La commande \"$CMDBEGIN\" s'est interrompue avec le code d'Erreur $STATUS ! (Durée : $TIME)" "$URL" &> /dev/null
fi
}
/usr/bin/time -q -f "%E %x %C" -o "$FILE" "$@"; boop2ntfy
local EXIT=$(awk 'NR==1{print $2}' "$FILE")
rm -f "$FILE"
return "$EXIT"
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# download a file from Google Drive with continuation : gdrive-dl ID FILENAME
gdrivedl() {
Help() {
cat <<- HEREDOC
Download a file from Google Drive with continuation.
Syntax: gdrive-dl [-h] <sharing ID from gdrive uri> <output file name>
options:
-h Print this Help.
HEREDOC
}
while getopts ":h" option; do
case $option in
h) Help; return 0 ;;
\?) echo -e "Unknown option: -$OPTARG \n" >&2; Help; return 1;;
: ) echo -e "Missing argument for -$OPTARG \n" >&2; Help; return 1;;
* ) echo -e "Unimplemented option: -$option \n" >&2; Help; return 1;;
esac
done
local _ID=$1
local _FILENAME=$2
wget --prefer-family=IPv4 --force-directories --no-check-certificate --no-hsts --continue --load-cookies "/tmp/gdrive-cookies-${_ID}.txt" \
"https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/gdrive-cookies-${_ID}.txt \
--keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=${_ID}' -O- | \
sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=${_ID}" -O "${XDG_DOWNLOAD_DIR}/$_FILENAME" \
&& rm -rf "/tmp/gdrive-cookies-${_ID}.txt"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# mans - print brief help about a single option or command
mans() {
Help() {
cat <<- HEREDOC 1>&2
Mans print brief help about a single option or command
Usage: mans <command> [<option|section>]
Example:
mans bash getopts Documentation for bash getopts
mans ssh -v Documentation for ssh -v flag
mans select SYNOPSIS for select(2)
mans 'open(2)' SYNOPSIS for open(2)
HEREDOC
}
if test $# -lt 1; then
Help
return 0
fi
manpage="$1"
# show the SYNOPSIS section if no section or option was given
option="${2:-SYNOPSIS}"
# handle manpage(number)
case $manpage in *\(*\))
page=${manpage%\(*\)}
section=${manpage#"$page"}
section=${section#\(}
section=${section%\)}
manpage="$page"
;;
esac
man ${section:+-s $section} "$manpage" | perl -n -e \
'BEGIN {
$option = "'"$option"'";
$inside_option = 0;
}
if (!$inside_option) {
if (/^(\s*)\Q$option\E\b/p) {
# start of this option
$option_indentation = $1;
$inside_option = 1;
$saw_blank_line = 0;
print;
}
} else {
if (/^$/) {
$saw_blank_line = 1;
print;
} elsif (/^\Q$option_indentation\E\S/ and $saw_blank_line) {
# item at same indentation => start of next option
$inside_option = 0;
} elsif (/^\S/) {
# new heading => start of next section
$inside_option = 0;
} else {
print;
}
}' | { if command -v hl 1> /dev/null; then hlauto --man; else cat -; fi }
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# br - This function starts broot and executes the command
if command -v br 1> /dev/null; then
br() {
local cmd cmd_file code
cmd_file=$(mktemp)
if broot --outcmd "$cmd_file" "$@"; then
cmd=$(<"$cmd_file")
command rm -f "$cmd_file"
eval "$cmd"
else
code=$?
command rm -f "$cmd_file"
return "$code"
fi
}
fi