34 Commits

Author SHA1 Message Date
fatalerrors
368bc11acf add many compression format to utaz 2026-03-05 10:55:17 +01:00
fatalerrors
a068d57ba5 utaz finally work with many formats, with optimizations 2026-03-05 10:24:25 +01:00
fatalerrors
ffee8c2e47 added help to rain, fixed french comments 2026-03-04 16:17:36 +01:00
geoffray.levasseur
9ff5792790 configurable rain 2026-03-04 15:55:11 +01:00
root
6a2d9b0fee adaptation to trixie and excalibur 2025-11-19 14:35:40 +01:00
Geoffray Levasseur-Brandin
9b2c764181 typos 2025-06-19 14:50:46 +02:00
Geoffray Levasseur-Brandin
3d5a5e7718 typos 2025-06-19 14:50:21 +02:00
Geoffray Levasseur-Brandin
47e89b3b09 compress.sh: multiple correction and securisation 2025-06-19 14:49:49 +02:00
Geoffray Levasseur-Brandin
f0f80e2924 better display implementation 2025-06-19 14:47:14 +02:00
Geoffray Levasseur-Brandin
b08e457146 version bump 2025-06-19 14:42:14 +02:00
Geoffray Levasseur-Brandin
56e34bc346 few varaible securisation, new alias hdu 2025-06-19 14:41:31 +02:00
Geoffray Levasseur-Brandin
e9e9993dfc finished profile_uprade implementation 2025-06-19 14:40:02 +02:00
Geoffray Levasseur-Brandin
ff4c6702b7 secured rmhost 2025-06-19 14:39:10 +02:00
Geoffray Levasseur-Brandin
87dea45295 fixed some variable declarations 2025-06-19 14:38:18 +02:00
Geoffray Levasseur-Brandin
0abf481cf6 various improvement and securisation 2025-06-19 14:37:32 +02:00
Geoffray Levasseur-Brandin
a75299f7b4 non gnu date compatible, use local vars where possible 2025-06-19 14:36:13 +02:00
Geoffray Levasseur-Brandin
eeb87c5bfc make delay parametrable 2025-06-19 14:34:22 +02:00
Geoffray Levasseur-Brandin
4879b418db factorized code / thiner implementation 2025-06-19 14:33:36 +02:00
Geoffray Levasseur-Brandin
f944271488 added file_stats function 2025-06-19 14:32:29 +02:00
Geoffray Levasseur-Brandin
4be2e5ea87 add url encode / secure isipv4 2025-06-19 14:31:19 +02:00
Geoffray Levasseur-Brandin
9d528a6491 fix kt function 2025-06-19 14:30:38 +02:00
Geoffray Levasseur-Brandin
bef205ae84 bugfix, esthetic cleanup, better comments, version bump 2024-06-21 16:19:44 +02:00
Geoffray Levasseur
9e49e3e4d7 fixed url and redirection 2023-10-06 12:52:15 +02:00
94e7e79c76 Merge branch 'master' of https://git.geoffray-levasseur.org/fatalerrors/profile 2023-10-06 11:36:14 +02:00
55e88bd018 partial commit for profile upgrade 2023-10-06 11:35:40 +02:00
Geoffray Levasseur
18f1bc1543 fix bash/zsh test, some cosmetics 2023-10-06 11:22:10 +02:00
fatalerrors
0d7c7e9ab7 minor correction 2023-09-08 20:25:04 +02:00
root
64fecf16fb make profile path configurable as autodetection is too unprecise so far 2023-04-19 21:15:33 +00:00
c2ca5f659c Version bumped to 3.3.1 (3.3.0 untagged) 2023-02-24 19:00:23 +01:00
3248327e56 [fix] don't use library functions before it's loaded 2023-02-23 14:43:44 +01:00
fd984c4a16 fixed version detection, added busy function 2023-02-03 08:09:20 +01:00
c2a0ef0bd2 Initial version update support, changed versioning code, add installation path detection 2023-02-03 07:55:06 +01:00
dc64123fd9 dpkgs -> pkgs, corrected package manager detection 2023-02-03 07:24:09 +01:00
affe6e1487 cpkgs: corrected invalid character in code 2022-11-30 21:00:13 +01:00
19 changed files with 1360 additions and 619 deletions

View File

@@ -7,6 +7,20 @@ Current version from Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
------------------------------------------------------------------------------
Version history:
------------------------------------------------------------------------------
# 04/03/2026 v3.5.0
rain has now configurable speed and color
showinfo adapted to fastfetch, replacing neofetch
# 24/02/2022 v3.3.1
Fixed version detection
Added "busy" function
Fixed use of library functions before it's loaded
# 28/11/2022 v3.3.0
Initial version update support
Changed versioning code
Added installation path detection
# 28/11/2022 v3.2.3
Made proper readme file, to improve

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -34,13 +35,110 @@
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Smartly uncompress archives (zip only)
# Smartly uncompress archives (zip only for now)
# ------------------------------------------------------------------------------
utaz()
{
for opt in $@ ; do
case $opt in
"-h"|"--help")
_ununzip()
{
unzip -o "$1" -d "$2" >/dev/null 2>&1
}
_untar()
{
tar -xf "$1" -C "$2"
}
_ungzip()
{
tar -xzf "$1" -C "$2"
}
_unbzip2()
{
tar -xjf "$1" -C "$2"
}
_unxz()
{
tar -xJf "$1" -C "$2"
}
_unlzop()
{
lzop -d "$1" -o "$2/$(basename "${1%.*}")"
}
_unlzip()
{
if command -v plzip >/dev/null 2>&1; then
plzip -d -c "$1" > "$2/$(basename "${1%.*}")"
else
lzip -d -c "$1" > "$2/$(basename "${1%.*}")"
fi
}
_ununrar()
{
unrar x -o+ "$1" "$2/" >/dev/null 2>&1
}
_ununarj()
{
unarj e "$1" "$2/" >/dev/null 2>&1
}
_unlza()
{
# lha typically extracts into the current directory
# We ensure it hits the target directory
(cd "$2" && lha -x "../$1") >/dev/null 2>&1
}
_ununace()
{
unace x "$1" "$2/" >/dev/null 2>&1
}
_un7z()
{
7z x "$1" -o"$2/" >/dev/null 2>&1
}
_unzstd()
{
# Zstd decompresses files directly, often requiring tar for archives
tar --zstd -xf "$1" -C "$2"
}
_uncpio()
{
# CPIO requires careful directory handling
(cd "$2" && cpio -id < "../$1") >/dev/null 2>&1
}
_uncabextract()
{
# Requires 'cabextract' package
cabextract "$1" -d "$2/" >/dev/null 2>&1
}
_undeb()
{
# Extracts data content from a Debian package
dpkg-deb -x "$1" "$2/" >/dev/null 2>&1
}
_unrpm()
{
# Extracts CPIO-based payload from an RPM package
# Needs rpm2cpio and cpio
rpm2cpio "$1" | (cd "$2/" && cpio -idmv) >/dev/null 2>&1
}
for opt in $@; do
case ${opt} in
"-h" | "--help")
echo "utaz: uncompress all the given files and/or the ones found in the given"
echo " directories creating an host directory where needed."
echo
@@ -55,15 +153,15 @@ utaz()
return 0
;;
"-d"|"--delete")
"-d" | "--delete")
local willrm=1
;;
"-c"|"--create-dir")
"-c" | "--create-dir")
local createdir=1
;;
"-n"|"--no-dir")
"-n" | "--no-dir")
local nodir=1
;;
@@ -75,58 +173,137 @@ utaz()
*)
# The ${opt%/} writing is to remove trailing / if any
local LIST="$LIST ${opt%/}"
local LIST="${LIST} ${opt%/}"
;;
esac
done
[[ $createdir && $nodir ]] && disp E "The --create-dir and --no-dir options are mutually exclusive."
[[ -n ${createdir} && -n ${nodir} ]] && \
disp E "The --create-dir and --no-dir options are mutually exclusive."
[[ ! $LIST ]] && local LIST="."
for zitem in $LIST; do
[[ $(ls $zitem/*.zip 2> /dev/null | wc -l) -eq 0 ]] &&
disp W "$zitem contains no supported archive file, skipping." &&
[[ -z ${LIST} ]] && local LIST="."
for zitem in ${LIST}; do
for f in "${zitem}"/*; do
local dir="${f%.*}"
local extractor=""
case "$f" in
*.zip)
extractor="_ununzip"
;;
*.tar.gz|*.tgz)
extractor="_ungzip"
;;
*.tar.bz2)
extractor="_unbzip2"
;;
*.tar.xz)
extractor="_unxz"
;;
*.tar.lz)
extractor="_unlzop"
;;
*.tar)
extractor="_untar"
;;
*.rar)
extractor="_ununrar"
;;
*.arj)
extractor="_ununarj"
;;
*.lzh|*.lha)
extractor="_unlha"
;;
*.ace)
extractor="_ununace"
;;
*.7z)
extractor="_un7z"
;;
*.zst)
extractor="_unzstd"
;;
*.cpio)
extractor="_uncpio"
;;
*.cab)
extractor="_uncabextract"
;;
*.deb)
extractor="_undeb"
;;
*.rpm)
extractor="_unrpm"
;;
*)
disp I "File ${f} is not a supported archive, skipping."
continue
;; # Skip non-archive files
esac
for f in $zitem/*.zip; do
disp I "Processing archive $zitem/$f... "
local dir=${f::-4}
# Verify binary existence
local cmd=${extractor//_un/}
if [[ $cmd == "deb" ]]; then
command -v dpkg-deb >/dev/null 2>&1 || {
disp E "The program 'dpkg-deb' is not installed, aborting."
continue
}
elif [[ $cmd == "rpm" ]]; then
command -v rpm2cpio >/dev/null 2>&1 || {
disp E "The program 'rpm2cpio' is not installed, aborting."
continue
}
command -v cpio >/dev/null 2>&1 || {
disp E "The program 'cpio' is not installed, aborting."
continue
}
else
command -v ${cmd} >/dev/null 2>&1 || {
disp E "Binary ${cmd} necessary to extract ${f} is missing."
continue
}
mkdir -p $dir
disp I "Processing archive ${f} with ${extractor}..."
mkdir -p "${dir}"
[[ $? -gt 0 ]] &&
disp E "The filesystem can't create directories, exit!" &&
return 1
unzip -o $f -d $dir > /dev/null 2>&1
${extractor} "${f}" "${dir}"
case $? in
0)
[[ $willrm ]] && rm -f $f && disp I "File $zitem/$f deleted."
[[ -n ${willrm} ]] &&
rm -f "${f}" && disp I "File ${zitem}/${f} deleted."
;;
1)
disp W "Compression program returned a warning: deletion canceled."
;;
*)
disp E "The zip file seems corrupted, failed."
rm -rf $dir > /dev/null 2>&1
rm -rf "${dir}" >/dev/null 2>&1
continue
;;
esac
if [[ $createdir ]]; then
if [[ -n ${createdir} ]]; then
disp I "Archive extracted successfully in subdirectory."
elif [[ $nodir ]]; then
mv ./$dir/* ./ && rmdir $dir
elif [[ -n ${nodir} ]]; then
mv "./${dir}/"* ./ && rmdir "${dir}"
disp I "Archive extracted successfully, no subdirectory needed."
else
subdirs=$(find $dir -maxdepth 1 | wc -l)
if [[ $subdirs -eq 2 ]]; then
mv ./$dir/* ./ && rmdir $dir
# Set nullglob to ensure the array is empty if no files match
shopt -s nullglob
local contents=( "${dir}"/* )
# Check if exactly one item exists and if that item is a directory
if [[ ${#contents[@]} -eq 1 ]] && [[ -d "${contents[0]}" ]]; then
# Single directory detected
mv "${contents[0]}"/* ./ && rmdir "${dir}"
disp I "Archive extracted successfully, no subdirectory needed."
else
disp I "Archive extracted successfully in subdirectory."
fi
shopt -u nullglob
fi
done
done
@@ -136,7 +313,7 @@ export -f utaz
# ------------------------------------------------------------------------------
# Compress directories or files into one or more archive
# ------------------------------------------------------------------------------
taz ()
taz()
{
_doxz()
{
@@ -166,11 +343,11 @@ taz ()
disp E "Program 'plzip' or 'lzip' are not installed, aborting."
return 127
}
local command=lzip
command=lzip
local procopt=""
[[ $2 -gt 1 ]] &&
disp W "lzip doesn't support multithreading, falling back to 1 thread." &&
disp W "Consitder installing plzip to obtain multithreading abilities."
disp W "Consider installing plzip to obtain multithreading abilities."
}
[[ $4 ]] && local verb="-vv"
@@ -194,7 +371,7 @@ taz ()
local procopt=""
[[ $2 -gt 1 ]] &&
disp W "gzip doesn't support multithreading, falling back to 1 thread." &&
disp W "Consitder installing pigz to obtain multithreading abilities."
disp W "Consider installing pigz to obtain multithreading abilities."
}
[[ $4 ]] && local verb="--verbose"
@@ -218,7 +395,7 @@ taz ()
local procopt=""
[[ $2 -gt 1 ]] &&
disp W "bzip2 doesn't support multithreading, falling back to 1 thread." &&
disp W "Consitder installing pbzip2 to obtain multithreading abilities."
disp W "Consider installing pbzip2 to obtain multithreading abilities."
}
[[ $4 ]] && local verb="-v"
@@ -243,9 +420,9 @@ taz ()
return $?
}
for opt in $@ ; do
for opt in $@; do
case $opt in
"-h"|"--help")
"-h" | "--help")
echo "taz: archive all files of a directory."
echo
echo "Usage: taz [option] [--parallel=<n>] [--format=<format>] [directory1 ... directoryN]"
@@ -273,24 +450,24 @@ taz ()
return 0
;;
"-d"|"--delete")
"-d" | "--delete")
local willrm=1
;;
"-f"?*|"--format"?*)
"-f"?* | "--format"?*)
local compform=$(echo "$opt" | cut -f 2- -d '=')
;;
"-p"?*|"--parallel"?*)
"-p"?* | "--parallel"?*)
local nproc=$(echo "$opt" | cut -f 2- -d '=')
;;
"-v"|"--verbose")
"-v" | "--verbose")
local verbose=1
;;
"-q"|"--quiet")
QUIET=1
"-q" | "--quiet")
local quiet=1
;;
"-"*)
@@ -311,17 +488,17 @@ taz ()
[[ ! $compform ]] && compform=lz # safe and efficient (unless data are already compressed)
[[ ! $nproc ]] && nproc=1
[[ ! $complevel ]] && complevel=6
[[ $verbose -gt 1 && $QUIET -gt 1 ]] &&
[[ $verbose -gt 1 && $quiet -gt 1 ]] &&
disp E "The --verbose and --quiet options can't be used together."
for item in $LIST; do
local donetar=0
disp I "Processing $item..."
if [[ -d $item ]]; then
if [[ -d "$item" ]]; then
disp I "\t Creating $item.tar... "
tar -cf $item{.tar,}
tar -cf "$item.tar" "$item"
if [[ ! $? -eq 0 ]]; then
disp E "tar file creation failed, skipping to next item."
continue
@@ -336,7 +513,7 @@ taz ()
# Skip compression part if tar is asked
if [[ $compform != "tar" ]]; then
disp I "\t Compressing archive..."
_do$compform $fname $nproc $complevel $verbose
_do$compform "$fname" "$nproc" "$complevel" "$verbose"
[[ ! $? -eq 0 ]] && case $? in
127)
disp E "Compression program unavailable, aborting."
@@ -348,14 +525,17 @@ taz ()
;;
esac
[[ $donetar -gt 0 ]] && rm $fname
[[ $donetar -gt 0 ]] && rm "$fname"
fi
if [[ $willrm ]]; then
disp I "\t Deleting original source as asked... "
rm -r $item
rm -r "$item"
fi
done
unset QUIET
unset quiet
}
export -f taz
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/bin/bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -36,7 +37,7 @@
# ------------------------------------------------------------------------------
# Display a backtrace
# ------------------------------------------------------------------------------
function backtrace ()
function backtrace()
{
echo "========= Call stack ========="
typeset -i i=0
@@ -45,7 +46,7 @@ function backtrace ()
for func in "${FUNCNAME[@]}"; do
if [[ $i -ne 0 ]]; then
printf '%15s() %s:%d\n' \
"$func" "${BASH_SOURCE[$i]}" "${BASH_LINENO[ (( $i - 1)) ]}"
"$func" "${BASH_SOURCE[$i]}" "${BASH_LINENO[(($i - 1))]}"
fi
let i++ || true
done
@@ -56,25 +57,24 @@ function backtrace ()
# ------------------------------------------------------------------------------
# Function to be trapped for errors investigation
# ------------------------------------------------------------------------------
function error ()
function error()
{
local errcode=$?
backtrace
return $errcode
}
# ------------------------------------------------------------------------------
# Activate or deactivate error trapping to display backtrace
# ------------------------------------------------------------------------------
settrace ()
settrace()
{
local status="off"
[[ $(trap -p ERR) ]] && status="on"
#trap -p ERR
for opt in $@ ; do
for opt in $@; do
case $opt in
"-h"|"--help")
"-h" | "--help")
echo "Try to activate backtrace display for script debugging."
echo
echo "Options:"
@@ -105,3 +105,6 @@ settrace ()
unset status
}
export -f settrace
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/bin/bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -40,6 +41,7 @@
export DEFAULTFG="\e[0;39m"
export DEFAULTBG="\e[0;49m"
export DEFAULTCOL=${DEFAULTBG}${DEFAULTFG}
export RESETCOL=$'\e[0m'
# Regular Colors
export Black='\e[0;30m'
@@ -111,7 +113,6 @@ export On_IPurple='\e[0;105m'
export On_ICyan='\e[0;106m'
export On_IWhite='\e[0;107m'
# ------------------------------------------------------------------------------
# Display a message
# ------------------------------------------------------------------------------
@@ -121,28 +122,31 @@ disp()
"I")
local heads="[ ${IGreen}info${DEFAULTFG} ]"
shift
[[ -z $QUIET || $QUIET -ne 1 ]] && echo -e "${heads} $@"
[[ -z $QUIET || $QUIET -ne 1 ]] && \
printf "%b\n" "${heads} $*${RESETCOL}"
;;
"W")
local heads="[ ${IYellow}Warning${DEFAULTFG} ]"
shift
echo -e "${heads} $@" >&2
printf "%b\n" "${heads} $*${RESETCOL}" >&2
;;
"E")
local heads="[ ${IRed}ERROR${DEFAULTFG} ]"
shift
echo -e "${heads} $@" >&2
printf "%b\n" "${heads} $*${RESETCOL}" >&2
;;
"D")
local heads"[ ${ICyan}debug${DEFAULTFG} ]"
local heads="[ ${ICyan}debug${DEFAULTFG} ]"
shift
[[ -n $DEBUG && $DEBUG -gt 1 ]] && echo -e "${heads} $@"
[[ -n $DEBUG && $DEBUG -gt 1 ]] && \
printf "%b\n" "${heads} $*${RESETCOL}"
;;
"*")
local heads=""
[[ -z $QUIET || $QUIET -ne 1 ]] && echo -e "$@"
* )
[[ -z $QUIET || $QUIET -ne 1 ]] && \
printf "%b\n" "$*"
;;
esac
unset heads
}
export -f disp
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -47,19 +48,18 @@ expandlist()
echo $result
}
# ------------------------------------------------------------------------------
# Clean a directory or a tree from temporary or backup files
# ------------------------------------------------------------------------------
clean ()
clean()
{
for opt in $@ ; do
for opt in $@; do
case $opt in
"-r"|"--recurs")
"-r" | "--recurs")
local recursive=1
;;
"-h"|"--help")
"-h" | "--help")
echo "clean: erase backup files in the given directories."
echo
echo "Usage: clean [option] [directory1] [...[directoryX]]"
@@ -73,11 +73,11 @@ clean ()
return 0
;;
"-s"|"--shell")
"-s" | "--shell")
local outshell=1
;;
"-f"|"--force")
"-f" | "--force")
local force=1
;;
@@ -100,7 +100,7 @@ clean ()
unset recursive force
for dir in $dirlist; do
local dellist=$(find $dir $findopt -type f -name "*~" -o -name "#*#" \
local dellist=$(find "$dir" $findopt -type f -name "*~" -o -name "#*#" \
-o -name "*.bak" -o -name ".~*#")
for f in $dellist; do
if [[ ! $outshell ]]; then
@@ -114,31 +114,29 @@ clean ()
}
export -f clean
# ------------------------------------------------------------------------------
# Create a directory then goes inside
# ------------------------------------------------------------------------------
mcd ()
mcd()
{
if [[ ! $# -eq 1 ]] ; then
if [[ ! $# -eq 1 ]]; then
disp E "Create a directory then goes inside."
disp E "Usage: mcd <directory>"
return 1
fi
mkdir -pv $1 && cd $1
mkdir -pv "$1" && cd "$1" || echo "Failed create or change directory."
}
export -f mcd
# ------------------------------------------------------------------------------
# Rename all files in current directory to replace spaces with _
# ------------------------------------------------------------------------------
rmspc ()
rmspc()
{
local lst=""
for opt in $@ ; do
for opt in $@; do
case $opt in
"-h"|"--help")
"-h" | "--help")
echo "rmspc: remove spaces from all filenames in current directories"
echo
echo "Usage: rmspc [option]"
@@ -156,11 +154,11 @@ rmspc ()
return 0
;;
"-r"|"--recursive")
"-r" | "--recursive")
local recurs=1
;;
"-c"?*|"--subst-char"?*)
"-c"?* | "--subst-char"?*)
if [[ $(echo $opt | grep "=") ]]; then
local substchar=$(echo "$opt" | cut -f 2- -d '=')
else
@@ -168,11 +166,11 @@ rmspc ()
fi
;;
"-v"|"--verbose")
"-v" | "--verbose")
local verb=1
;;
"-s"|"--shell")
"-s" | "--shell")
local shell=1
;;
@@ -192,9 +190,9 @@ rmspc ()
[[ $recurs ]] && [[ -d "$f" ]] && (
[[ $verb ]] && disp I "Entering directory $(pwd)/$f ..."
local lastdir=$f
pushd "$f" > /dev/null
pushd "$f" >/dev/null
rmspc $@
popd > /dev/null
popd >/dev/null
[[ $verb ]] && disp I "Leaving directory $(pwd)/$lastdir"
unset lastdir
)
@@ -212,3 +210,135 @@ rmspc ()
unset lst substchar verb shell newf command mvopt
}
export -f rmspc
# ------------------------------------------------------------------------------
# display stats about a file structure
# ------------------------------------------------------------------------------
file_stats()
{
local human=0 details=0 only_avg=0 only_med=0 only_count=0 only_total=0
local path="." show_all=1 ext_filter="" ext_list="" min_size="" max_size=""
local OPTIND opt
# Analyse options
while [[ "$1" =~ ^- ]]; do
case "$1" in
-H) human=1 ;;
-d) details=1 ;;
-m) only_avg=1; show_all=0 ;;
-M) only_med=1; show_all=0 ;;
-c) only_count=1; show_all=0 ;;
-t) only_total=1; show_all=0 ;;
-a) human=1; details=1 ;;
-x) ext_filter="${2#.}"; shift ;;
-X) ext_list="${2}"; shift ;;
--min) min_size="$2"; shift ;;
--max) max_size="$2"; shift ;;
--) shift; break ;;
-*) echo "Usage: file_stats [-h] [-d] [-mMctaxX --min N --max N] [path]"; return 1 ;;
esac
shift
done
[ -n "$1" ] && path="$1"
# Prepare find filters
local find_cmd=(find "$path" -type f)
# Extension simple
if [[ -n "$ext_filter" ]]; then
find_cmd+=(-iname "*.$ext_filter")
fi
# Extension liste
if [[ -n "$ext_list" ]]; then
IFS=',' read -ra exts <<< "$ext_list"
find_cmd+=('(')
for i in "${!exts[@]}"; do
[[ $i -ne 0 ]] && find_cmd+=(-o)
find_cmd+=(-iname "*.${exts[$i]}")
done
find_cmd+=(')')
fi
# Taille min/max (à évaluer en octets)
if [[ -n "$min_size" ]]; then
find_cmd+=(-size +"$(numfmt --from=iec "$min_size")"c)
fi
if [[ -n "$max_size" ]]; then
find_cmd+=(-size -"$(( $(numfmt --from=iec "$max_size") + 1 ))"c)
fi
# Exécution
"${find_cmd[@]}" -printf "%s\n" 2>/dev/null | sort -n | awk -v human="$human" -v details="$details" -v only_avg="$only_avg" -v only_med="$only_med" -v only_count="$only_count" -v only_total="$only_total" -v show_all="$show_all" -v path="$path" '
function human_readable(x) {
split("B KiB MiB GiB TiB", units)
for (i=1; x>=1024 && i<5; i++) x /= 1024
return sprintf("%.2f %s", x, units[i])
}
{
sizes[NR] = $1
total += $1
if (min == "" || $1 < min) min = $1
if (max == "" || $1 > max) max = $1
if ($1 == 0) bucket[0]++
else {
b = int(log($1)/log(1024))
bucket[b]++
}
}
END {
count = NR
if (count == 0) {
print "Aucun fichier trouvé."; exit
}
moyenne = total / count
if (count % 2 == 1)
mediane = sizes[(count + 1) / 2]
else
mediane = (sizes[count / 2] + sizes[count / 2 + 1]) / 2
function out(label, val) {
if (human) val = human_readable(val)
printf "%-20s : %s\n", label, val
}
if (only_avg) out("Taille moyenne", moyenne)
else if (only_med) out("Taille médiane", mediane)
else if (only_count) printf "Nombre de fichiers : %d\n", count
else if (only_total) out("Taille totale", total)
else {
if (show_all || human || details) {
printf "Statistiques sur \"%s\"\n", path
printf "-------------------------\n"
}
out("Nombre de fichiers", count)
out("Taille totale", total)
out("Taille moyenne", moyenne)
out("Taille médiane", mediane)
out("Taille minimale", min)
out("Taille maximale", max)
}
if (details) {
print "\nHistogramme des tailles :"
for (i = 0; i in bucket; i++) {
low = 2^i
high = 2^(i+1)
if (i == 0)
label = sprintf("%4s %4s", "0", "1K")
else
label = sprintf("%4s %4s", human_readable(low), human_readable(high))
printf "%-20s : %5d fichiers\n", label, bucket[i]
}
}
}'
}
export -f file_stats
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# EOF

70
profile.d/fun.sh Normal file
View File

@@ -0,0 +1,70 @@
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
#
# * Redistribution and use in source and binary forms,
# * with or without modification, are permitted provided
# * that the following conditions are met:
# *
# * Redistributions of source code must retain the above
# * copyright notice, this list of conditions and the
# * following disclaimer.
# *
# * Redistributions in binary form must reproduce the above
# * copyright notice, this list of conditions and the following
# * disclaimer in the documentation and/or other materials
# * provided with the distribution.
# *
# * Neither the name of the copyright holder nor the names
# * of any other contributors may be used to endorse or
# * promote products derived from this software without
# * specific prior written permission.
# *
# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# * OF SUCH DAMAGE.
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Make non-IT peoples think you're busy doing something hard
# ------------------------------------------------------------------------------
busy()
{
local pattern="ca fe"
for arg in "$@"; do
case "$arg" in
--delay=*)
delay_ms="${arg#*=}"
if ! [[ $delay_ms =~ ^[0-9]+$ ]]; then
disp E "Invalid delay value, must be an integer (milliseconds)."
return 1
fi
;;
*)
pattern="$arg"
;;
esac
done
# Convert milliseconds to seconds for 'sleep'
local delay_s=$(awk "BEGIN { printf \"%.3f\", $delay_ms / 1000 }")
cat /dev/urandom | hexdump -C | grep --line-buffered "$pattern" | \
while read -r line; do
echo $line
[[ $delay_ms -gt 0 ]] && sleep "$delay_s"
done
unset pattern
}
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/bin/bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -66,3 +67,5 @@ EOF
}
export -f help
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/bin/bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -36,28 +37,31 @@
# ------------------------------------------------------------------------------
# Show profile version
# ------------------------------------------------------------------------------
ver ()
ver()
{
[[ -z $PROFVERSION ]] && \
disp W "No version defined. Profile is probably badly installed." && \
return 1
disp "Profile version $PROFVERSION."
}
export -f ver
# ------------------------------------------------------------------------------
# Display weather of the given city (or default one)
# ------------------------------------------------------------------------------
meteo ()
meteo()
{
cities=$@
[[ $# -eq 0 ]] && local cities=$DEFAULT_CITY
local encoded cities=("$@")
[[ $# -eq 0 ]] && cities=("$DEFAULT_CITY")
for city in $cities; do
curl https://wttr.in/$city || disp E "Failed fetching datas for $city."
for city in "${cities[@]}"; do
encoded=$(urlencode "$city")
curl -s "https://wttr.in/$encoded" || \
disp E "Failed fetching datas for $city."
done
}
export -f meteo
# ------------------------------------------------------------------------------
# Display system general information
# ------------------------------------------------------------------------------
@@ -68,23 +72,33 @@ showinfo()
if [[ -s /usr/share/figlet/ansi_shadow.flf ]]; then
local figopt="-f ansi_shadow"
fi
figlet -k $(hostname) $figopt
if [[ -n $figopt ]]; then
figlet -k $figopt $(hostname)
else
echo "$(hostname -f)"
figlet $(hostname)
fi
else
hostname -f
fi
echo ""
if command -v neofetch >/dev/null 2>&1; then
neofetch
elif command -v fastfetch >/dev/null 2>&1; then
fastfetch
else
(
if [[ -s /etc/os-release ]]; then
# shellcheck disable=SC1091
. /etc/os-release
echo "$NAME $VERSION"
else
cat /proc/version
fi
echo "Uptime: $(uptime)"
echo "Uptime: $(uptime -p)"
)
fi
}
export -f showinfo
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/bin/bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -33,38 +34,69 @@
# * OF SUCH DAMAGE.
# ------------------------------------------------------------------------------
locale_check() {
locale -a | grep -qx "$1" || {
disp W "Locale '$1' is not installed on this system."
return 1
}
return 0
}
# ------------------------------------------------------------------------------
# Change locale to the given one in parameter
# ------------------------------------------------------------------------------
setlocale()
{
local loc=$1
[[ -z $loc ]] && disp E "No locale specified." && return 1
locale_check "$loc" || return 1
export LANG=$loc
export LC_MESSAGES=$loc
export LC_TIME=$loc
export LC_NUMERIC=$loc
export LC_MONETARY=$loc
export LC_COLLATE=$loc
export LC_CTYPE=$loc
disp I "Locale set to $loc."
}
export -f setlocale
# ------------------------------------------------------------------------------
# Special case : change locale to C standard
# ------------------------------------------------------------------------------
setc()
{
# Locale definitions
export LC_ALL=C
disp I "Locale changed to standard C (POSIX)."
}
export -f setc
# ------------------------------------------------------------------------------
# Change locale to French
# ------------------------------------------------------------------------------
setfr ()
setfr()
{
# Set fr locale definitions
export LANG=fr_FR.UTF-8
export LC_MESSAGES=fr_FR.UTF-8
export LC_ALL=fr_FR.UTF-8
setlocale "fr_FR.UTF-8"
}
export -f setfr
# ------------------------------------------------------------------------------
# Change locale to C standard
# ------------------------------------------------------------------------------
setc ()
{
# Locale definitions
export LANG=C
export LC_MESSAGES=C
export LC_ALL=C
}
export -f setc
# ------------------------------------------------------------------------------
# Change locale to US (needed by Steam)
# ------------------------------------------------------------------------------
setus ()
setus()
{
# Locale definitions
export LANG=en_US.UTF-8
export LC_MESSAGES=en_US.UTF-8
export LC_ALL=en_US.UTF-8
setlocale "en_US.UTF-8"
}
export -f setus
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/bin/bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -36,10 +37,11 @@
# ------------------------------------------------------------------------------
# Determine if parameter is a valid IPv4 address
# ------------------------------------------------------------------------------
isipv4 ()
isipv4()
{
# Set up local variables
local ip=$1
[[ -z $ip ]] && return 1
# Start with a regex format test
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
@@ -47,8 +49,8 @@ isipv4 ()
IFS="."
ip=($ip)
IFS=$old_ifs
if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then
if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 &&
${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then
if [[ -t 1 ]]; then
disp "The given IPv4 is valid."
fi
@@ -62,11 +64,10 @@ isipv4 ()
}
export -f isipv4
# ------------------------------------------------------------------------------
# Determine if parameter is a valid IPv4 address
# ------------------------------------------------------------------------------
isipv6 ()
isipv6()
{
local ip="$1"
local regex='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$'
@@ -82,3 +83,25 @@ isipv6 ()
return 1
}
export -f isipv6
# ------------------------------------------------------------------------------
# Encode a string so it can be used as a URL parameter
# ------------------------------------------------------------------------------
urlencode() {
local LANG=C
local str="$*"
local length="${#str}"
for (( i = 0; i < length; i++ )); do
local c="${str:i:1}"
case "$c" in
[a-zA-Z0-9.~_-]) printf "$c" ;;
' ') printf '+' ;;
*) printf '%%%02X' "'$c" #| cut -d' ' -f2 ;;
esac
done
}
export -f urlencode
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/bin/bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -36,12 +37,12 @@
# ------------------------------------------------------------------------------
# Look for a package within installed one
# ------------------------------------------------------------------------------
dpkgs ()
pkgs()
{
local count=0
for opt in $@ ; do
for opt in $@; do
case $opt in
"-h"|"--help")
"-h" | "--help")
echo "dpkgs: look for an installed package by it's name."
echo
echo "Usage: dpkgs <string>"
@@ -56,7 +57,7 @@ dpkgs ()
*)
local pkg=$1 && shift
count=$(( $count + 1 ))
count=$(($count + 1))
[[ $count -gt 1 ]] &&
disp E "Please specify a package name, without space, eventually partial." &&
return 1
@@ -68,13 +69,15 @@ dpkgs ()
disp E "Please specify a package name, without space, eventually partial." &&
return 1
if [[ $(command -v dpkg >/dev/null 2>&1) ]]; then
dpkg -l | grep $pkg
elif [[ $(command -v rpm >/dev/null 2>&1) ]]; then
rpm -qa | grep $pkg
else
command -v dpkg >/dev/null 2>&1 && local cmd="dpkg -l"
command -v rpm >/dev/null 2>&1 && local cmd="rpm -qa"
if [[ -z $cmd ]]; then
disp E "No usable package manager seems unavialable."
return 2
fi
$cmd | grep $pkg
}
export -f dpkgs
export -f pkgs
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/bin/bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -36,17 +37,16 @@
# ------------------------------------------------------------------------------
# Search processes matching the given string
# ------------------------------------------------------------------------------
ppg ()
ppg()
{
ps -edf | grep $@ | grep -v "grep $@"
ps -edf | grep "$@" | grep -v "grep $@"
}
export -f ppg
# ------------------------------------------------------------------------------
# Get PID list of the given process name
# ------------------------------------------------------------------------------
gpid ()
gpid()
{
[[ $UID -eq 0 ]] && local psopt="-A"
[[ $# -eq 1 ]] && local single=1
@@ -62,14 +62,33 @@ gpid ()
}
export -f gpid
# ------------------------------------------------------------------------------
# Kill all processes owned by the given users
# ------------------------------------------------------------------------------
ku ()
ku()
{
for u in $@; do
killall -u $u
killall -u "$u"
done
}
export -f ku
# ------------------------------------------------------------------------------
# Kill all children of a process then the process
# ------------------------------------------------------------------------------
kt()
{
[[ -z $1 ]] && echo -e "Usage:\n\tkt <pid> [kill_options]"
local parent_pid="$1"
shift
children_pids=$(pgrep -P "$parent_pid")
for pid in $children_pids; do
kt "$pid" "$@"
done
kill "$@" "$parent_pid"
}
# ------------------------------------------------------------------------------
# EOF

View File

@@ -38,7 +38,7 @@
# ------------------------------------------------------------------------------
function timer_now
{
date +%s%N
date +%s%N 2>/dev/null || date +%s
}
function timer_start
@@ -76,21 +76,21 @@ function timer_stop
# ------------------------------------------------------------------------------
# Function triguered internaly by bash : defining prompt
# ------------------------------------------------------------------------------
set_prompt ()
set_prompt()
{
Last_Command=$? # Must come first!
Blue='\[\e[0;34m\]'
White='\[\e[01;37m\]'
Yellow='\[\e[01;93m\]'
Red='\[\e[01;31m\]'
Green='\[\e[01;32m\]'
OnGrey='\[\e[47m\]'
OnRed='\[\e[41m\]'
OnBlue='\[\e[44m\]'
ICyan='\[\e[0;96m\]'
Default='\[\e[00m\]'
FancyX='\342\234\227'
Checkmark='\342\234\223'
local Last_Command=$? # Must come first!
local Blue='\[\e[0;34m\]'
local White='\[\e[01;37m\]'
local Yellow='\[\e[01;93m\]'
local Red='\[\e[01;31m\]'
local Green='\[\e[01;32m\]'
local OnGrey='\[\e[47m\]'
local OnRed='\[\e[41m\]'
local OnBlue='\[\e[44m\]'
local ICyan='\[\e[0;96m\]'
local Default='\[\e[00m\]'
local FancyX='\342\234\227'
local Checkmark='\342\234\223'
# Begin with time
PS1="\[\e[s$Blue$OnGrey [ \t ] $OnBlue"
@@ -123,3 +123,6 @@ set_prompt ()
# the text color to the default.
PS1+="$ICyan\\w \\\$$Default "
}
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -44,10 +45,11 @@ genpwd()
local occurs=2 # Bug, if set to 1, seems to be ignored
local symb=1 maj=1 min=1 numb=1
local nbpwd=1
local extcar
for opt in $@; do
case $opt in
"-h"|"--help")
"-h" | "--help")
echo "genpwd: generate one or more secure random password."
echo
echo "Usage: genpwd [options] [--extracars=<cars>] [--length=<n>] [nb_passwd]"
@@ -75,29 +77,29 @@ genpwd()
echo
return 0
;;
"-s"|"--nosymbols")
"-s" | "--nosymbols")
symb=0
;;
"-n"|"--nonumbers")
"-n" | "--nonumbers")
numb=0
;;
"-u"|"--noup")
"-u" | "--noup")
maj=0
;;
"-l"|"--nolow")
"-l" | "--nolow")
min=0
;;
"-e"?*|"--extracars"?*)
local extcar=$(echo "$opt" | cut -f 2- -d '=')
"-e"?* | "--extracars"?*)
extcar=$(echo "$opt" | cut -f 2- -d '=')
;;
"-L"?*|"--length"?*)
"-L"?* | "--length"?*)
local length=$(echo "$opt" | cut -f 2- -d '=')
if ! [[ $length =~ ^[0-9]+$ ]]; then
disp E "The --length parameter requires a number."
return 1
fi
;;
"-o"?*|"--occurences"?*)
"-o"?* | "--occurences"?*)
local occurs=$(echo "$opt" | cut -f 2- -d '=')
if ! [[ $occurs =~ ^[1-9]+$ ]]; then
disp E "The --occurs parameter requires a number from 1 to 9."
@@ -113,20 +115,19 @@ genpwd()
disp E "Unknow parameter ${opt}."
return 1
else
local nbpwd=$opt
nbpwd=$opt
fi
;;
esac
done
# Function selecting a random caracter from the list in parameter
pickcar()
{
pickcar() {
# When a character is picked we check if it's not appearing already twice
# elsewhere, we choose an other char, to compensate weak bash randomizer
while [[ -z $char ]]; do
local char=$(echo ${1:RANDOM%${#1}:1} $RANDOM)
if [[ $(awk -F"$char" '{print NF-1}' <<< "$picked") -gt $occurs ]]; then
local char="${1:RANDOM%${#1}:1} $RANDOM"
if [[ $(awk -F"$char" '{print NF-1}' <<<"$picked") -gt $occurs ]]; then
unset char
fi
done
@@ -135,7 +136,7 @@ genpwd()
}
disp I "Generating $nbpwd passwords, please wait..."
for n in $( seq 1 $nbpwd ); do
for n in $(seq 1 $nbpwd); do
{
local carset='' # store final caracter set to use
local picked='' # store already used caracter
@@ -145,27 +146,27 @@ genpwd()
if [[ $symb == 1 ]]; then
pickcar '!.@#&%/^-_'
carset+='!.@#&%/^-_'
(( rlength++ ))
((rlength++))
fi
if [[ $numb == 1 ]]; then
pickcar '0123456789'
carset+='0123456789'
(( rlength++ ))
((rlength++))
fi
if [[ $maj == 1 ]]; then
pickcar 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
carset+='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
(( rlength++ ))
((rlength++))
fi
if [[ $min == 1 ]]; then
pickcar 'abcdefghijklmnopqrstuvwxyz'
carset+='abcdefghijklmnopqrstuvwxyz'
(( rlength++ ))
((rlength++))
fi
if [[ -n $extcar ]]; then
pickcar "$extcar"
carset+=$extcar
(( rlength++ ))
((rlength++))
fi
# Check if we have enough car to have something viable
@@ -175,7 +176,7 @@ genpwd()
return 1
fi
for i in $( seq 1 $(( $length - $rlength )) ); do
for i in $(seq 1 $(($length - $rlength))); do
pickcar "$carset"
done
} | sort -R | awk '{printf "%s", $1}'
@@ -184,3 +185,6 @@ genpwd()
done
}
export -f genpwd
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -38,34 +39,98 @@
# ------------------------------------------------------------------------------
rain()
{
show_usage() {
echo -e "Usage: rain [OPTIONS]"
echo -e ""
echo -e "Options:"
echo -e " -s, --speed NUM Set the drop delay in seconds (default: 0.050)."
echo -e " Lower values = faster rain."
echo -e " -c, --color COLOR Set the color theme (default: white)."
echo -e " -h, --help Display this help message and exit."
echo -e ""
echo -e "Available Colors:"
echo -e " \e[32mgreen\e[0m : The classic Matrix digital rain"
echo -e " \e[34mblue\e[0m : Deep ocean blue gradients"
echo -e " \e[31mred\e[0m : Crimson/Blood rain"
echo -e " \e[33myellow\e[0m : Amber and gold tones"
echo -e " \e[36mcyan\e[0m : Electric cyan/turquoise"
echo -e " white : Greyscale and white (original style)"
echo -e ""
echo -e "Example: rain --color green --speed 0.03"
}
local step_duration=0.050
local base_color="white" # default color scheme, can be overridden by --color
# Analyse arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
-s|--speed)
if [[ -n "$2" && ! "$2" =~ ^- ]]; then
step_duration="$2"; shift
else
echo -e "\e[31mError: --speed requires a numeric value.\e[0m"
show_usage && return 1
fi
;;
-c|--color)
if [[ -n "$2" && ! "$2" =~ ^- ]]; then
base_color="$2"; shift
else
echo -e "\e[31mError: --color requires a color name.\e[0m"
show_usage && return 1
fi
;;
-h|--help)
show_usage && return 0
;;
*)
echo -e "\e[31mUnknown option: $1\e[0m"
show_usage && return 1
;;
esac
shift
done
# Define colors (256-colors gradients)
local rain_colors=()
case $base_color in
green) # Matrix style green
for i in {22..28} {34..40} {46..48}; do rain_colors+=("\e[38;5;${i}m"); done ;;
blue) # Deep ocean blues
for i in {17..21} {27..33} {39..45}; do rain_colors+=("\e[38;5;${i}m"); done ;;
red) # Crimson / blood red
for i in {52..52} {88..88} {124..124} {160..160} {196..201}; do rain_colors+=("\e[38;5;${i}m"); done ;;
yellow) # Amber / gold
for i in {58..58} {100..100} {142..142} {184..184} {226..229}; do rain_colors+=("\e[38;5;${i}m"); done ;;
cyan) # Electric cyan / turquoise
for i in {30..31} {37..38} {44..45} {50..51}; do rain_colors+=("\e[38;5;${i}m"); done ;;
*) # Greyscale / white (original style)
rain_colors=("\e[37m" "\e[37;1m")
for i in {244..255}; do rain_colors+=("\e[38;5;${i}m"); done ;;
esac
local exit_st=0
local rain_cars=("|" "│" "┃" "┆" "┇" "┊" "┋" "╽" "╿")
local rain_colors=("\e[37m" "\e[37;1m")
# More from 256 color mode
for i in {244..255}; do
rain_colors=( "${rain_colors[@]}" "\e[38;5;${i}m" )
done
local rain_tab=${#rain_cars[@]}
local rain_color_tab=${#rain_colors[@]}
local num_rain_metadata=5
local term_height=$(tput lines)
local term_width=$(tput cols)
local step_duration=0.050
local X=0 Y=0 drop_length=0 rain_drop=0
local max_rain_width=0 new_rain_odd=0 falling_odd=0
sigwinch() {
term_width=$(tput cols)
term_height=$(tput lines)
#step_duration=0.025
(( max_rain_width = term_width * term_height / 4 ))
(( max_rain_height = term_height < 10 ? 1 : term_height / 10 ))
((max_rain_width = term_width * term_height / 4))
((max_rain_height = term_height < 10 ? 1 : term_height / 10))
# In percentage
(( new_rain_odd = term_height > 50 ? 100 : term_height * 2 ))
(( new_rain_odd = new_rain_odd * 75 / 100 ))
(( falling_odd = term_height > 25 ? 100 : term_height * 4 ))
(( falling_odd = falling_odd * 90 / 100 ))
((new_rain_odd = term_height > 50 ? 100 : term_height * 2))
((new_rain_odd = new_rain_odd * 75 / 100))
((falling_odd = term_height > 25 ? 100 : term_height * 4))
((falling_odd = falling_odd * 90 / 100))
}
do_exit() {
@@ -80,19 +145,19 @@ rain()
Y=${rains[idx + 1]}
drop_length=${rains[idx + 4]}
for ((y = Y; y < Y + drop_length; y++)); do
(( y < 1 || y > term_height )) && continue
((y < 1 || y > term_height)) && continue
echo -ne "\e[${y};${X}H "
done
done
for ((idx = 0; idx < num_rains * num_rain_metadata; idx += num_rain_metadata)); do
if (( 100 * RANDOM / 32768 < falling_odd )); then
if ((100 * RANDOM / 32768 < falling_odd)); then
# Falling
if (( ++rains[idx + 1] > term_height )); then
if ((++rains[idx + 1] > term_height)); then
# Out of screen, bye sweet <3
rains=("${rains[@]:0:idx}"
"${rains[@]:idx+num_rain_metadata:num_rains*num_rain_metadata}")
(( num_rains-- ))
((num_rains--))
continue
fi
fi
@@ -102,7 +167,7 @@ rain()
drop_color=${rains[idx + 3]}
drop_length=${rains[idx + 4]}
for ((y = Y; y < Y + drop_length; y++)); do
(( y < 1 || y > term_height )) && continue
((y < 1 || y > term_height)) && continue
echo -ne "\e[${y};${X}H${drop_color}${rain_drop}"
done
done
@@ -118,24 +183,24 @@ rain()
local rains=()
local num_rains=0
sigwinch
while (( exit_st <= 0 )); do
if (( $exit_st <=0 )); then
while ((exit_st <= 0)); do
if (($exit_st <= 0)); then
read -n 1 -t $step_duration ch
case "$ch" in
q|Q)
q | Q)
do_exit
;;
esac
if (( num_rains < max_rain_width )) && (( 100 * RANDOM / 32768 < new_rain_odd )); then
if ((num_rains < max_rain_width)) && ((100 * RANDOM / 32768 < new_rain_odd)); then
# Need new |, 1-based
rain_drop="${rain_cars[rain_tab * RANDOM / 32768]}"
drop_color="${rain_colors[rain_color_tab * RANDOM / 32768]}"
drop_length=$(( max_rain_height * RANDOM / 32768 + 1 ))
X=$(( term_width * RANDOM / 32768 + 1 ))
Y=$(( 1 - drop_length ))
rains=( "${rains[@]}" "$X" "$Y" "$rain_drop" "$drop_color" "$drop_length" )
(( num_rains++ ))
drop_length=$((max_rain_height * RANDOM / 32768 + 1))
X=$((term_width * RANDOM / 32768 + 1))
Y=$((1 - drop_length))
rains=("${rains[@]}" "$X" "$Y" "$rain_drop" "$drop_color" "$drop_length")
((num_rains++))
fi
# Let rain fall!
@@ -152,3 +217,6 @@ rain()
trap - WINCH
}
export -f rain
# ------------------------------------------------------------------------------
# EOF

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
@@ -36,7 +37,7 @@
# ------------------------------------------------------------------------------
# Remove host from know_host (name and IP) for the active user
# ------------------------------------------------------------------------------
rmhost ()
rmhost()
{
if [[ "$#" -lt 1 ]]; then
disp E "Incorrect number of parameters."
@@ -46,9 +47,9 @@ rmhost ()
while [[ $1 ]]; do
local hst=$1 && shift
isipv4 $hst > /dev/null
isipv4 "$hst" >/dev/null
local v4=$?
isipv6 $hst > /dev/null
isipv6 "$hst" >/dev/null
local v6=$?
if [[ $v4 -eq 0 || $v6 -eq 0 ]]; then
@@ -58,34 +59,37 @@ rmhost ()
unset v4 v6
if [[ ! $ip && $hst ]]; then
ip=$(host $hst | grep "has address" | awk '{print $NF}')
[[ ! $? ]] &&
if ! ip=$(host "$hst" 2>/dev/null | awk '/has address/ {print $NF; exit}'); then
disp E "Impossible to extract IP from hostname." &&
return 1
fi
[[ -z $ip ]] && {
disp E "Impossible to extract IP from hostname."
return 1;
}
fi
if [[ $hst ]]; then
disp I "Removing host $hst from ssh known_host..."
ssh-keygen -R $hst > /dev/null
ssh-keygen -R $hst >/dev/null
fi
if [[ $ip ]]; then
disp I "Removing IP $ip from ssh known_host..."
ssh-keygen -R $ip > /dev/null
ssh-keygen -R $ip >/dev/null
fi
unset hst ip
done
}
export -f rmhost
# ------------------------------------------------------------------------------
# Login root via SSH on the given machine
# ------------------------------------------------------------------------------
ssr ()
ssr()
{
for opt in $@ ; do
for opt in $@; do
case $opt in
"-h"|"--help")
"-h" | "--help")
echo "ssr: do a root user ssh login."
echo
echo "Usage: ssr <server [ssh options]>"
@@ -94,12 +98,19 @@ ssr ()
esac
done
command -v ssh >/dev/null 2>&1 || {
disp E "ssh is not installed."
return 127
}
[[ ! $1 ]] &&
disp E "Please specify the server you want to log in." &&
return 1
local srv=$1 && shift
ssh -Y root@$srv $@
ssh -Y root@"$srv" "$@"
}
export -f ssr
# ------------------------------------------------------------------------------
# EOF

135
profile.d/updates.sh Normal file
View File

@@ -0,0 +1,135 @@
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
#
# * Redistribution and use in source and binary forms,
# * with or without modification, are permitted provided
# * that the following conditions are met:
# *
# * Redistributions of source code must retain the above
# * copyright notice, this list of conditions and the
# * following disclaimer.
# *
# * Redistributions in binary form must reproduce the above
# * copyright notice, this list of conditions and the following
# * disclaimer in the documentation and/or other materials
# * provided with the distribution.
# *
# * Neither the name of the copyright holder nor the names
# * of any other contributors may be used to endorse or
# * promote products derived from this software without
# * specific prior written permission.
# *
# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# * OF SUCH DAMAGE.
# ------------------------------------------------------------------------------
export BASE_URL="https://git.geoffray-levasseur.org/fatalerrors/profile"
export UPDT_URL="$BASE_URL/raw/branch/master"
export ARCH_URL="$BASE_URL/archive/master.tar.gz"
# ------------------------------------------------------------------------------
# Check for profile updates
# ------------------------------------------------------------------------------
check_updates()
{
if [[ $1 == "-q" ]]; then
# Quiet mode is mostly used internally when profile_upgrade is called
quiet=1
fi
disp I "Checking for updates..."
local vfile="/tmp/version"
wget "$UPDT_URL/version" -O $vfile >/dev/null 2>&1 || {
disp E "Can't download version file, impossible to proceed!"
return 5
}
if [[ -s $vfile ]]; then
local lastver=$(cat $vfile)
if [[ $lastver != $PROFVERSION ]]; then
disp I "You have version $PROFVERSION installed. Version $lastver is available."
[[ $quiet ]] && disp I "You should upgrade to last version when possible."
result=1
else
disp I "Your version is up-to-date."
result=0
fi
rm -f $vfile
else
disp E "Impossible to read temporary file, impossible to proceed."
fi
unset lastver vfile
return $result
}
# ------------------------------------------------------------------------------
# Apply update to profile
# ------------------------------------------------------------------------------
profile_upgrade()
{
check_updates -q
local need_update=$?
[[ $need_update -ne 1 ]] && {
disp "No update available."
return 0
}
if [[ -s $MYPATH/profile.sh ]]; then
disp E "Installation path detection failed, cannot upgrade automatically."
return 1
fi
if [[ -d $MYPATH/.git ]]; then
disp I "Git installation detected, applying git pull."
local curdir=$(pwd)
cd $MYPATH
git pull || {
disp E "Git pull failed, upgrade not applyed."
cd "$curdir"
return 2
}
disp I "Successfully upgraded using git."
cd "$curdir"
else
disp I "No Git detected. Downloading and applying upgrade from archive..."
local tmpdir="/tmp/profile_upg.$$"
mkdir -p "$tmpdir" || {
disp E "Failed to create temporary directory."
return 4
}
local archive="$tmpdir/profile.tar.gz"
wget -q "$ARCH_URL" -O "$archive" || {
disp E "Failed to download archive."
rm -rf "$tmpdir"
return 5
}
tar -xzf "$archive" -C "$tmpdir" || {
disp E "Archive extraction failed."
rm -rf "$tmpdir"
return 6
}
disp I "Installing new version..."
cp -r "$tmpdir"/profile/* "$MYPATH"/ || {
disp E "Failed to copy new files to $MYPATH."
rm -rf "$tmpdir"
return 7
}
disp I "Upgrade complete. You should now logout and login again."
rm -rf "$tmpdir"
fi
}
# EOF

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Begin profile
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
@@ -35,12 +35,8 @@
# * OF SUCH DAMAGE.
# ------------------------------------------------------------------------------
export PROFVERSION="3.2.3"
export DEFAULT_CITY="Toulouse"
if [[ ! $(echo $SHELL | grep bash) ]]; then
echo "That environmet script is designed to be used with bash or zsh being the shell."
if [[ ! $SHELL =~ bash|zsh ]]; then
echo "That environment script is designed to be used with bash or zsh being the shell."
echo "Please consider using bash or zsh instead, or patch me ;)!"
return 1
fi
@@ -48,49 +44,71 @@ fi
# ------------------------------------------------------------------------------
# path* : private functions for PATH variable management
# ------------------------------------------------------------------------------
pathremove ()
pathremove()
{
local ifs=':'
local IFS=':'
local newpath
local dir
local pathvar=${2:-PATH}
for dir in ${!pathvar} ; do
if [ "$dir" != "$1" ] ; then
for dir in ${!pathvar}; do
if [ "$dir" != "$1" ]; then
newpath=${newpath:+$newpath:}$dir
fi
done
export $pathvar="$newpath"
}
pathprepend ()
pathprepend()
{
pathremove $1 $2
local pathvar=${2:-PATH}
export $pathvar="$1${!pathvar:+:${!pathvar}}"
}
pathappend ()
pathappend()
{
pathremove $1 $2
local pathvar=${2:-PATH}
export $pathvar="${!pathvar:+${!pathvar}:}$1"
}
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# ********************************** MAIN PROGRAM ******************************
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Store script's path (realpath -s resolve symlinks if profile.sh is a symlink)
if [[ -z "$PROFILE_PATH" ]]; then
export MYPATH=$(dirname "$(realpath -s "$0")")
else
export MYPATH="$PROFILE_PATH"
fi
if [[ ! -e "$MYPATH/profile.sh" ]]; then
echo "[ Warning ] Path detection failed, trying to use pwd..."
MYPATH=$(pwd)
if [[ ! -e "$MYPATH/profile.sh" ]]; then
echo "[ Error ] Impossible to determine installation path, pretty much nothing will work."
fi
fi
if [[ ! -s "$MYPATH/version" ]]; then
echo "[ Warning ] Impossible to determine running version of profile, your installation might be broken."
fi
export PROFVERSION=$(cat "$MYPATH"/version)
# Build PATH environment variable
if [[ $EUID -eq 0 ]] ; then
if [[ $EUID -eq 0 ]]; then
pathappend /sbin:/usr/sbin
fi
[[ -d /share/services/gestparc ]] && pathappend /share/services/gestparc
[[ -d ~/bin ]] && pathappend ~/bin
[[ -d ~/.local/bin ]] && pathappend ~/.local/bin
# ------------------------------------------------------------------------------
# Default values are set here and will be overloaded with config file if any
# ------------------------------------------------------------------------------
# Set bash history
export HISTSIZE=50000
export HISTIGNORE="&:[bf]g:exit"
@@ -106,17 +124,22 @@ export CFLAGS="-O2 -pipe -march=native"
export MAKEFLAGS='-j12'
export PKGSOURCES='/share/src/archives'
# Default city for weather forcast
export DEFAULT_CITY="Toulouse"
# ------------------------------------------------------------------------------
# Default values could be altered after this line
# ------------------------------------------------------------------------------
# Load global configuration
[[ -f $MYPATH/etc/profile.conf ]] && . $MYPATH/etc/profile.conf
# Load personal configuration
[[ -f ~/.profile.conf ]] && . ~/.profile.conf
# Execute optionnal config script if any
for script in ~/profile.d/*.sh ; do
if [ -r $script ] ; then
# Load module scripts
for script in $MYPATH/profile.d/*.sh; do
if [[ -r $script ]]; then
. $script
fi
done
@@ -152,6 +175,7 @@ if [[ $INTERACTIVE ]]; then
alias du='du -ch'
alias sdu='du -sk ./* | sort -n'
alias hdu='du -hs ./* | sort -H'
# Define PS1
trap 'timer_start' DEBUG

1
version Normal file
View File

@@ -0,0 +1 @@
3.4.0