Compare commits
74 Commits
v3.2.2
...
96d1dc695d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96d1dc695d | ||
|
|
c039ab6ea0 | ||
|
|
6b85556a53 | ||
|
|
cf9a85e61b | ||
|
|
75e047d70e | ||
|
|
742ec484a7 | ||
|
|
1b7262c0cd | ||
|
|
e387209c10 | ||
|
|
f5d59ec194 | ||
|
|
2ee1c935ac | ||
|
|
e41c1a4c51 | ||
|
|
60dfe19049 | ||
|
|
c32771a4ff | ||
|
|
080511d0bd | ||
|
|
d8bdfefdf1 | ||
|
|
5f5f9c0e71 | ||
|
|
30387a4f08 | ||
|
|
0c51363d86 | ||
|
|
043fbaef0b | ||
|
|
ed5587712e | ||
|
|
58cc76c317 | ||
|
|
e82ee06e1d | ||
|
|
bc8cb4a237 | ||
|
|
ae90a9f4c4 | ||
|
|
7e661ca2de | ||
|
|
9f22ed4304 | ||
|
|
1484b004be | ||
|
|
0a4206b890 | ||
|
|
02a1e25df2 | ||
|
|
7ca0a6fb88 | ||
|
|
25df408e37 | ||
|
|
3eab1f98d5 | ||
|
|
6c895b509a | ||
|
|
2ece711e1a | ||
|
|
39a7e7b40f | ||
|
|
6d5d872b71 | ||
|
|
128cfe8c87 | ||
|
|
e1c2705fdd | ||
|
|
368bc11acf | ||
|
|
a068d57ba5 | ||
|
|
ffee8c2e47 | ||
|
|
9ff5792790 | ||
|
|
6a2d9b0fee | ||
|
|
9b2c764181 | ||
|
|
3d5a5e7718 | ||
|
|
47e89b3b09 | ||
|
|
f0f80e2924 | ||
|
|
b08e457146 | ||
|
|
56e34bc346 | ||
|
|
e9e9993dfc | ||
|
|
ff4c6702b7 | ||
|
|
87dea45295 | ||
|
|
0abf481cf6 | ||
|
|
a75299f7b4 | ||
|
|
eeb87c5bfc | ||
|
|
4879b418db | ||
|
|
f944271488 | ||
|
|
4be2e5ea87 | ||
|
|
9d528a6491 | ||
|
|
bef205ae84 | ||
|
|
9e49e3e4d7 | ||
| 94e7e79c76 | |||
| 55e88bd018 | |||
|
|
18f1bc1543 | ||
|
|
0d7c7e9ab7 | ||
|
|
64fecf16fb | ||
| c2ca5f659c | |||
| 3248327e56 | |||
| fd984c4a16 | |||
| c2a0ef0bd2 | |||
| dc64123fd9 | |||
| affe6e1487 | |||
| 0237f8bf70 | |||
| d4db72260a |
112
README.md
112
README.md
@@ -1,3 +1,113 @@
|
|||||||
# profile
|
# profile
|
||||||
|
This project aims to create an advanced bash profile. It includes some aliases,
|
||||||
|
a customized prompt and several functions for different purposes. It's mostly
|
||||||
|
targeted to system administrator but might satisfy some regular users.
|
||||||
|
|
||||||
bash profile repository
|
## 1. Getting started
|
||||||
|
Download and extract (or use git clone) the profile archive into your home
|
||||||
|
directory. You will have to modify your ~/.bashrc and/or ~/.profile file to add
|
||||||
|
at the end (preferably):
|
||||||
|
```
|
||||||
|
source <installpath>/profile/profile.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
It's not recommended to load that profile in /etc/profile as the users' .bashrc
|
||||||
|
files might interfere with some aliases and functions defined in profile.
|
||||||
|
|
||||||
|
## 2. What's the purpose?
|
||||||
|
profile is giving access to numerous functions, aliases and to an advanced
|
||||||
|
prompt. Here is a non-exhaustive list of what we have:
|
||||||
|
- A bar style prompt with hour, execution time and exit code of the last
|
||||||
|
command;
|
||||||
|
- clean: erase after confirmation any backup file, possibly recursively;
|
||||||
|
- dwl: a curl/wget/fetch download wrapper;
|
||||||
|
- pkgs: search for the given pattern in the installed packages name;
|
||||||
|
- expandlist: usefull in scripts, it expand any expression using wildcards into
|
||||||
|
the corresponding list of file and directories;
|
||||||
|
- genpwd: generate one or more random secure password;
|
||||||
|
- gpid: give the list of PID matching the given process name;
|
||||||
|
- help: display the list of available function and basic use;
|
||||||
|
- isipv4: tell if the given parameter is a valid IPv4 address;
|
||||||
|
- isipv6: tell if the given parameter is a valid IPv6 address;
|
||||||
|
- ku: kill all the processes owned by the given user name or ID;
|
||||||
|
- mcd: create a directory and immediately move into it;
|
||||||
|
- meteo: display weather forecast information;
|
||||||
|
- myextip: get informations about your public IP;
|
||||||
|
- ppg: look for the given patern in the running processes;
|
||||||
|
- rain: console screensaver with rain effect;
|
||||||
|
- rmhost: remove the given host (name or IP) to the list of SSH known host;
|
||||||
|
- rmspc: in the current directory it replace all the spaces in filenames with a
|
||||||
|
underscore caracter (or any other given in option);
|
||||||
|
- setc: set locale on standard C;
|
||||||
|
- setfr: set locale on French;
|
||||||
|
- settrace: allow the debugging of any script by showing a backtrace in case of
|
||||||
|
error;
|
||||||
|
- setus: set locale on US English;
|
||||||
|
- showinfo: display basic informations about the host;
|
||||||
|
- ssr: root ssh login to the given host;
|
||||||
|
- taz: a universal command to compress files and directories, possibly several
|
||||||
|
at once;
|
||||||
|
- utaz: a utility that smartly uncompress many archives at once, creating a
|
||||||
|
directory only if needed;
|
||||||
|
- ver: show profile version.
|
||||||
|
|
||||||
|
## 3. Configuration
|
||||||
|
Some functions might have configurable default behaviour. You can create a
|
||||||
|
profile.conf file to configure those default behaviour. You should have a look
|
||||||
|
at the doc/profile.conf.example to see the list of available options. The
|
||||||
|
configuration file is located in the same directory as profile.sh file.
|
||||||
|
|
||||||
|
## 4. Contact and more information
|
||||||
|
### 4.1. New users
|
||||||
|
This project is very new in terms of publication, and I have no idea of who will
|
||||||
|
use it, if any does. If you use (or plan to use) ```profile```, I'll be very
|
||||||
|
happy if you simply mail me to let me know, especially if you don't plan to
|
||||||
|
contribute. If you plan to contribute, I'll be twice happier for sure!
|
||||||
|
|
||||||
|
### 4.2. Bugs
|
||||||
|
**profile** bug tracker is hosted on its Gitea instance. Check the
|
||||||
|
https://git.geoffray-levasseur.org/fatalerrors/profile page. If you find a bug,
|
||||||
|
you can also submit a bug report to the maintainer mail address mentioned at
|
||||||
|
the end of that document. A bug report may contain the command line parameters
|
||||||
|
where the bug happens, OS details, the module that trigger it, if any, and the
|
||||||
|
log file containing the error. Cygwin users: please note that bash
|
||||||
|
implementation in Cygwin triggers regularly bugs on advanced code that triggers
|
||||||
|
nothing with Linux or BSD. Please do not send synthax error bug repports if you
|
||||||
|
didn't test the same code in the same conditions using a real Unix.
|
||||||
|
|
||||||
|
Please check the to-do list before sending any feature request, as it might
|
||||||
|
have already be requested.
|
||||||
|
|
||||||
|
### 4.3. How to contribute?
|
||||||
|
You are free to improve and contribute as you wish. If you have no idea what to
|
||||||
|
do or want some direction, you can check the [to-do list](./doc/todo.md),
|
||||||
|
containing desired future improvements. Make sure you always have the latest
|
||||||
|
development version before starting your work.
|
||||||
|
|
||||||
|
It's heavily recommended to use git to obtain the latest copy of profile tree.
|
||||||
|
Make sure your git configuration is correct in order to contribute. Please
|
||||||
|
contact me to obtain push authorizations, or, if you want to submit a patch, you
|
||||||
|
can send it by mail to the maintainer of init.sh.
|
||||||
|
|
||||||
|
Code written in Python or Perl might be accepted as long as it's not mobilizing
|
||||||
|
a lot of dependencies (forget big framework). Anything that need the
|
||||||
|
installation of packages not provided in minimal Debian or CentOS installation
|
||||||
|
will be probably rejected.
|
||||||
|
|
||||||
|
If you want to make a financial contribution, please contact me by mail.
|
||||||
|
|
||||||
|
### 4.4. License, website, and maintainer
|
||||||
|
Everything except configuration files is licensed under BSD-3 license. Please
|
||||||
|
check license file allong this one.
|
||||||
|
|
||||||
|
Please check [https://www.geoffray-levasseur.org/profile](https://www.geoffray-levasseur.org/profile).
|
||||||
|
Note that this website is still under construction and needs some more care.
|
||||||
|
|
||||||
|
You can mail author to fatalerrors \<at\> geoffray-levasseur \<dot\> org.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Documentation (c) 2021-2022 Geoffray Levasseur.
|
||||||
|
|
||||||
|
This file is distributed under3-clause BSD license. The complete license
|
||||||
|
agreement can be obtained at: https://opensource.org/licenses/BSD-3-Clause
|
||||||
|
|||||||
25
history.txt
25
history.txt
@@ -7,6 +7,31 @@ Current version from Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Version history:
|
Version history:
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
# 05/03/2026 v3.6.1
|
||||||
|
Fix a typo in compress.sh
|
||||||
|
|
||||||
|
# 05/03/2026 v3.6.0
|
||||||
|
Improved utaz to make it multiformat with lot of it
|
||||||
|
Introduced ppu and ppn
|
||||||
|
Improved update system
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
# 21/11/2022 v3.2.2
|
# 21/11/2022 v3.2.2
|
||||||
Fixed taz compression level analysis
|
Fixed taz compression level analysis
|
||||||
Fixed typo in dpkgs
|
Fixed typo in dpkgs
|
||||||
|
|||||||
95
profile.conf
Executable file
95
profile.conf
Executable file
@@ -0,0 +1,95 @@
|
|||||||
|
[system]
|
||||||
|
# System section is used to set Bash behavior and other system related
|
||||||
|
# variables, such as the default pager, the terminal type, etc.
|
||||||
|
# Set bash history
|
||||||
|
HISTSIZE=50000
|
||||||
|
HISTIGNORE="&:[bf]g:exit"
|
||||||
|
|
||||||
|
# Set default pager
|
||||||
|
PAGER=less
|
||||||
|
|
||||||
|
# Set terminal colors behavior
|
||||||
|
TERM=xterm-256color
|
||||||
|
|
||||||
|
[compress]
|
||||||
|
# Section used by compress.sh
|
||||||
|
|
||||||
|
[debug]
|
||||||
|
# Section used by debug.sh
|
||||||
|
|
||||||
|
[disp]
|
||||||
|
# Section used by disp.sh
|
||||||
|
# Set to any value to disable colors in internal profile output (not controling binary output)
|
||||||
|
# NO_COLOR=1
|
||||||
|
|
||||||
|
[filefct]
|
||||||
|
# Section used by filefct.sh
|
||||||
|
|
||||||
|
[fun]
|
||||||
|
# Section used by fun.sh
|
||||||
|
|
||||||
|
[info]
|
||||||
|
# Section used by info.sh
|
||||||
|
# Default city for weather forcast and local news
|
||||||
|
DEFAULT_CITY="Toulouse"
|
||||||
|
|
||||||
|
[lang]
|
||||||
|
# Section used by lang.sh
|
||||||
|
# List of locale shortcuts to build, in the form "shortcut:locale,...".
|
||||||
|
# Generate a function setXX for each shortcut defined.
|
||||||
|
SET_LOCALE="fr:fr_FR.UTF-8,us:en_US.UTF-8"
|
||||||
|
|
||||||
|
[net]
|
||||||
|
# Section used by net.sh
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
# Section used by packages.sh
|
||||||
|
|
||||||
|
[prompt]
|
||||||
|
# Section used by prompt.sh
|
||||||
|
|
||||||
|
[pwd]
|
||||||
|
# Section used by pwd.sh
|
||||||
|
|
||||||
|
[rain]
|
||||||
|
# Section used by rain.sh
|
||||||
|
|
||||||
|
[ssh]
|
||||||
|
# Section used by ssh.sh
|
||||||
|
|
||||||
|
[updates]
|
||||||
|
# Section used by updates.sh
|
||||||
|
|
||||||
|
[general]
|
||||||
|
# General section allow to set any variable that can be used by the user.
|
||||||
|
# It is also a good place to set freely global variables for personal use.
|
||||||
|
# Set some compiling values
|
||||||
|
CFLAGS="-O2 -pipe -march=native"
|
||||||
|
CXXFLAGS="$CFLAGS"
|
||||||
|
MAKEFLAGS='-j12'
|
||||||
|
PKGSOURCES='/share/src/archives'
|
||||||
|
|
||||||
|
[aliases]
|
||||||
|
ll='ls -laFh --color=auto'
|
||||||
|
la='ls -Ah --color=auto'
|
||||||
|
l='ls -CF --color=auto'
|
||||||
|
ls='ls --color=auto'
|
||||||
|
|
||||||
|
grep='grep --color=auto'
|
||||||
|
egrep='egrep --color=auto'
|
||||||
|
fgrep='fgrep --color=auto'
|
||||||
|
qfind="find . -name "
|
||||||
|
|
||||||
|
mkck='make check'
|
||||||
|
mkin='make install'
|
||||||
|
mkdin='make DESTDIR=$PWD/dest-install install'
|
||||||
|
ssh='ssh -Y'
|
||||||
|
|
||||||
|
wget='wget -c' # resume mode by default
|
||||||
|
myip='curl ip.appspot.com'
|
||||||
|
|
||||||
|
# Human readable by default
|
||||||
|
df='df -H'
|
||||||
|
du='du -ch'
|
||||||
|
sdu='du -sk ./* | sort -n'
|
||||||
|
hdu='du -hs ./* | sort -H'
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -34,108 +35,350 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Smartly uncompress archives (zip only)
|
# Smartly uncompress archives
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: utaz [option] [directorie(s)|file(s)]
|
||||||
|
# Options:
|
||||||
|
# -h, --help Display that help screen
|
||||||
|
# -d, --delete If decompression succeeded, delete the source file
|
||||||
|
# -c, --create-dir Always create a host directory
|
||||||
|
# -n, --no-dir Never create a host directory
|
||||||
utaz()
|
utaz()
|
||||||
{
|
{
|
||||||
for opt in $@ ; do
|
_ununzip()
|
||||||
case $opt in
|
{
|
||||||
"-h"|"--help")
|
unzip -o "$1" -d "$2" >/dev/null 2>&1
|
||||||
echo "utaz: uncompress all the given files and/or the ones found in the given"
|
}
|
||||||
echo " directories creating an host directory where needed."
|
|
||||||
echo
|
_untar()
|
||||||
echo "Usage: utaz [option] [directorie(s)|file(s)]"
|
{
|
||||||
echo
|
tar -xf "$1" -C "$2"
|
||||||
echo "Options:"
|
}
|
||||||
echo " -h, --help Display that help screen"
|
|
||||||
echo " -d, --delete If decompression succeeded, delete the source file"
|
_ungzip()
|
||||||
echo " -c, --create-dir Always create a host directory"
|
{
|
||||||
echo " -n, --no-dir Never create a host directory"
|
tar -xzf "$1" -C "$2"
|
||||||
echo
|
}
|
||||||
|
|
||||||
|
_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
|
||||||
|
}
|
||||||
|
|
||||||
|
local PARSED=$(getopt -o hdcn --long help,delete,create-dir,no-dir -n 'utaz' -- "$@")
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
disp E "Invalid options, use \"utaz --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "utaz: uncompress all the given files and/or the ones found in the given\n"
|
||||||
|
printf " directories creating an host directory where needed.\n\n"
|
||||||
|
printf "Usage: utaz [option] [directorie(s)|file(s)]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay that help screen\n"
|
||||||
|
printf "\t-d, --delete\t\tIf decompression succeeded, delete the source file\n"
|
||||||
|
printf "\t-c, --create-dir\tAlways create a host directory\n"
|
||||||
|
printf "\t-n, --no-dir\t\tNever create a host directory\n\n"
|
||||||
|
printf "Supported archive format:\n"
|
||||||
|
printf "\t- zip\n"
|
||||||
|
printf "\t- tar.gz, .tgz\n"
|
||||||
|
printf "\t- tar.bz2, .tbz2\n"
|
||||||
|
printf "\t- tar.xz, .txz\n"
|
||||||
|
printf "\t- tar.lz, .tlz\n"
|
||||||
|
printf "\t- rar\n"
|
||||||
|
printf "\t- arj\n"
|
||||||
|
printf "\t- lha, lzh\n"
|
||||||
|
printf "\t- ace\n"
|
||||||
|
printf "\t- 7z, p7z\n"
|
||||||
|
printf "\t- zst\n"
|
||||||
|
printf "\t- cpio\n"
|
||||||
|
printf "\t- cab\n"
|
||||||
|
printf "\t- deb\n"
|
||||||
|
printf "\t- rpm\n"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
-d|--delete)
|
||||||
"-d"|"--delete")
|
|
||||||
local willrm=1
|
local willrm=1
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
|
-c|--create-dir)
|
||||||
"-c"|"--create-dir")
|
|
||||||
local createdir=1
|
local createdir=1
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
|
-n|--no-dir)
|
||||||
"-n"|"--no-dir")
|
|
||||||
local nodir=1
|
local nodir=1
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
|
--)
|
||||||
"-"*)
|
shift
|
||||||
disp E "Invalid option, use \"utaz --help\" to display options list"
|
break
|
||||||
echo
|
|
||||||
return 1
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
# The ${opt%/} writing is to remove trailing / if any
|
disp E "Invalid option, use \"utaz --help\" to display options list"
|
||||||
local LIST="$LIST ${opt%/}"
|
return 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
# The remaining arguments after -- are the files/directories to process,
|
||||||
|
# "." is used if none is given
|
||||||
|
local FILES=("$@")
|
||||||
|
[[ ${#FILES[@]} -eq 0 ]] && FILES=(".")
|
||||||
|
|
||||||
[[ $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 "${FILES[@]}"; do
|
||||||
|
# Build list of input files to process, with whitespace-safe handling.
|
||||||
for zitem in $LIST; do
|
local targets=()
|
||||||
[[ $(ls $zitem/*.zip 2> /dev/null | wc -l) -eq 0 ]] &&
|
if [[ -f "$zitem" ]]; then
|
||||||
disp W "$zitem contains no supported archive file, skipping." &&
|
targets=("$zitem")
|
||||||
|
elif [[ -d "$zitem" ]]; then
|
||||||
|
mapfile -d '' -t targets < <(find "$zitem" -mindepth 1 -maxdepth 1 -print0 2>/dev/null)
|
||||||
|
if [[ ${#targets[@]} -eq 0 ]]; then
|
||||||
|
disp I "Directory ${zitem} is empty, skipping."
|
||||||
continue
|
continue
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
disp W "Path ${zitem} is not a file or directory, skipping."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
for f in $zitem/*.zip; do
|
for f in "${targets[@]}"; do
|
||||||
disp I "Processing archive $zitem/$f... "
|
local dir="${f%.*}"
|
||||||
local dir=${f::-4}
|
local extractor=""
|
||||||
|
case "$f" in
|
||||||
|
*.zip)
|
||||||
|
extractor="_ununzip"
|
||||||
|
;;
|
||||||
|
*.tar.gz|*.tgz)
|
||||||
|
extractor="_ungzip"
|
||||||
|
;;
|
||||||
|
*.tar.bz2|*.tbz2)
|
||||||
|
extractor="_unbzip2"
|
||||||
|
;;
|
||||||
|
*.tar.xz|*.txz)
|
||||||
|
extractor="_unxz"
|
||||||
|
;;
|
||||||
|
*.tar.lz|*.tlz)
|
||||||
|
extractor="_unlzop"
|
||||||
|
;;
|
||||||
|
*.tar)
|
||||||
|
extractor="_untar"
|
||||||
|
;;
|
||||||
|
*.rar)
|
||||||
|
extractor="_ununrar"
|
||||||
|
;;
|
||||||
|
*.arj)
|
||||||
|
extractor="_ununarj"
|
||||||
|
;;
|
||||||
|
*.lzh|*.lha)
|
||||||
|
extractor="_unlha"
|
||||||
|
;;
|
||||||
|
*.ace)
|
||||||
|
extractor="_ununace"
|
||||||
|
;;
|
||||||
|
*.7z|*.p7z)
|
||||||
|
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
|
||||||
|
|
||||||
mkdir -p $dir
|
# 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
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
disp I "Processing archive ${f} with ${extractor}..."
|
||||||
|
mkdir -p "${dir}"
|
||||||
[[ $? -gt 0 ]] &&
|
[[ $? -gt 0 ]] &&
|
||||||
disp E "The filesystem can't create directories, exit!" &&
|
disp E "The filesystem can't create directories, exit!" &&
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
unzip -o $f -d $dir > /dev/null 2>&1
|
${extractor} "${f}" "${dir}"
|
||||||
case $? in
|
case $? in
|
||||||
0)
|
0)
|
||||||
[[ $willrm ]] && rm -f $f && disp I "File $zitem/$f deleted."
|
[[ -n ${willrm} ]] &&
|
||||||
|
rm -f "${f}" && disp I "File ${zitem}/${f} deleted."
|
||||||
;;
|
;;
|
||||||
|
|
||||||
1)
|
1)
|
||||||
|
if [[ -n ${willrm} ]]; then
|
||||||
disp W "Compression program returned a warning: deletion canceled."
|
disp W "Compression program returned a warning: deletion canceled."
|
||||||
|
else
|
||||||
|
disp W "Compression program returned a warning."
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
disp E "The zip file seems corrupted, failed."
|
disp E "The compressed file ${f} seems corrupted, failed."
|
||||||
rm -rf $dir > /dev/null 2>&1
|
rm -rf "${dir}" >/dev/null 2>&1
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ $createdir ]]; then
|
if [[ -n ${createdir} ]]; then
|
||||||
disp I "Archive extracted successfully in subdirectory."
|
disp I "Archive extracted successfully in subdirectory."
|
||||||
elif [[ $nodir ]]; then
|
elif [[ -n ${nodir} ]]; then
|
||||||
mv ./$dir/* ./ && rmdir $dir
|
shopt -s nullglob
|
||||||
|
for child in "${dir}"/*; do
|
||||||
|
mv -- "$child" .
|
||||||
|
done
|
||||||
|
shopt -u nullglob
|
||||||
|
rmdir -- "${dir}"
|
||||||
disp I "Archive extracted successfully, no subdirectory needed."
|
disp I "Archive extracted successfully, no subdirectory needed."
|
||||||
else
|
else
|
||||||
subdirs=$(find $dir -maxdepth 1 | wc -l)
|
# Set nullglob to ensure the array is empty if no files match
|
||||||
if [[ $subdirs -eq 2 ]]; then
|
shopt -s nullglob
|
||||||
mv ./$dir/* ./ && rmdir $dir
|
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
|
||||||
|
shopt -s nullglob
|
||||||
|
for child in "${contents[0]}"/*; do
|
||||||
|
mv -- "$child" .
|
||||||
|
done
|
||||||
|
shopt -u nullglob
|
||||||
|
rmdir -- "${dir}"
|
||||||
disp I "Archive extracted successfully, no subdirectory needed."
|
disp I "Archive extracted successfully, no subdirectory needed."
|
||||||
else
|
else
|
||||||
disp I "Archive extracted successfully in subdirectory."
|
disp I "Archive extracted successfully in subdirectory."
|
||||||
fi
|
fi
|
||||||
|
shopt -u nullglob
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
export -f utaz
|
export -f utaz
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Compress directories or files into one or more archive
|
# Compress directories or files into one or more archive
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: taz [option] [--parallel=<n>] [--format=<format>] [directory1 ... directoryN]
|
||||||
|
# Options:
|
||||||
|
# -h, --help Display that help screen
|
||||||
|
# -d, --delete Delete source file or directory after success
|
||||||
|
# -f, --format Chose archive format in the given list. If several format are
|
||||||
|
# given, the smalest is kept
|
||||||
|
# -p, --parallel Number of threads to use (if allowed by underlying utility)
|
||||||
|
# -v, --verbose Display progress where possible
|
||||||
|
# -q, --quiet Display less messages (only errors and warnings)
|
||||||
|
# -1, .., -9 Compression level to use [1=fast/biggest, 9=slow/smallest]
|
||||||
taz()
|
taz()
|
||||||
{
|
{
|
||||||
_doxz()
|
_doxz()
|
||||||
@@ -166,11 +409,11 @@ taz ()
|
|||||||
disp E "Program 'plzip' or 'lzip' are not installed, aborting."
|
disp E "Program 'plzip' or 'lzip' are not installed, aborting."
|
||||||
return 127
|
return 127
|
||||||
}
|
}
|
||||||
local command=lzip
|
command=lzip
|
||||||
local procopt=""
|
local procopt=""
|
||||||
[[ $2 -gt 1 ]] &&
|
[[ $2 -gt 1 ]] &&
|
||||||
disp W "lzip doesn't support multithreading, falling back to 1 thread." &&
|
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"
|
[[ $4 ]] && local verb="-vv"
|
||||||
@@ -194,7 +437,7 @@ taz ()
|
|||||||
local procopt=""
|
local procopt=""
|
||||||
[[ $2 -gt 1 ]] &&
|
[[ $2 -gt 1 ]] &&
|
||||||
disp W "gzip doesn't support multithreading, falling back to 1 thread." &&
|
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"
|
[[ $4 ]] && local verb="--verbose"
|
||||||
@@ -218,7 +461,7 @@ taz ()
|
|||||||
local procopt=""
|
local procopt=""
|
||||||
[[ $2 -gt 1 ]] &&
|
[[ $2 -gt 1 ]] &&
|
||||||
disp W "bzip2 doesn't support multithreading, falling back to 1 thread." &&
|
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"
|
[[ $4 ]] && local verb="-v"
|
||||||
@@ -243,85 +486,99 @@ taz ()
|
|||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
for opt in $@ ; do
|
local PARSED
|
||||||
case $opt in
|
PARSED=$(getopt -o hdf:p:vq123456789 --long help,delete,format:,parallel:,verbose,quiet --name "taz" -- "$@")
|
||||||
"-h"|"--help")
|
if [ $? -ne 0 ]; then
|
||||||
echo "taz: archive all files of a directory."
|
disp E "Invalid options, use \"taz --help\" to display usage."
|
||||||
echo
|
return 1
|
||||||
echo "Usage: taz [option] [--parallel=<n>] [--format=<format>] [directory1 ... directoryN]"
|
fi
|
||||||
echo
|
eval set -- "$PARSED"
|
||||||
echo "Options:"
|
while true; do
|
||||||
echo " -h, --help Display that help screen"
|
case "$1" in
|
||||||
echo " -d, --delete Delete source file or directory after success"
|
-h|--help)
|
||||||
echo " -f, --format Chose archive format in the given list. If several format are"
|
printf "taz: archive all files of a directory.\n\n"
|
||||||
echo " given, the smalest is kept"
|
printf "Usage: taz [option] [--parallel=<n>] [--format=<format>] [directory1 ... directoryN]\n\n"
|
||||||
echo " -p, --parallel Number of threads to use (if allowed by underlying utility)"
|
printf "Options:\n"
|
||||||
echo " -v, --verbose Display progress where possible"
|
printf "\t-h, --help\tDisplay that help screen\n"
|
||||||
echo " -q, --quiet Display less messages (only errors and warnings)"
|
printf "\t-d, --delete\tDelete source file or directory after success\n"
|
||||||
echo " -1, .., -9 Compression level to use [1=fast/biggest, 9=slow/smallest]"
|
printf "\t-f, --format\tChose archive format in the given list. If several format are"
|
||||||
echo
|
printf "\t\t\tgiven, the smalest is kept\n"
|
||||||
echo "Supported archive format:"
|
printf "\t-p, --parallel\tNumber of threads to use (if allowed by underlying utility)\n"
|
||||||
echo " Param.| programs | Algo. | Description"
|
printf "\t-v, --verbose\tDisplay progress where possible\n"
|
||||||
echo " ------+---------------+-------+----------------------------------------"
|
printf "\t-q, --quiet\tDisplay less messages (only errors and warnings)\n"
|
||||||
echo " lz | plzip, lzip | lzma | Safe efficient default format"
|
printf "\t-1, .., -9\tCompression level to use [1=fast/biggest, 9=slow/smallest]\n\n"
|
||||||
echo " xz | xz | lzma2 | Unsafe, not for long term"
|
printf "Supported archive format:\n"
|
||||||
echo " bz2 | pbzip2, bzip2 | bzip2 | Historical but less efficient than lz"
|
printf "\tParam.| programs | Algo. | Description\n"
|
||||||
echo " gz | pigz, gzip | lz77 | Historical, safe, fast"
|
printf "\t------+---------------+-------+----------------------------------------\n"
|
||||||
echo " lzo | lzop | lzo | Very fast but no multithread"
|
printf "\t lz | plzip, lzip | lzma | Safe efficient default format\n"
|
||||||
echo " tar | tar | tar | No compression"
|
printf "\t xz | xz | lzma2 | Unsafe, not for long term\n"
|
||||||
echo
|
printf "\t bz2 | pbzip2, bzip2 | bzip2 | Historical but less efficient than lz\n"
|
||||||
|
printf "\t gz | pigz, gzip | lz77 | Historical, safe, fast\n"
|
||||||
|
printf "\t lzo | lzop | lzo | Very fast but no multithread\n"
|
||||||
|
printf "\t tar | tar | tar | No compression\n"
|
||||||
|
printf "\n"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"-d"|"--delete")
|
-d|--delete)
|
||||||
local willrm=1
|
local willrm=1
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"-f"?*|"--format"?*)
|
-f|--format)
|
||||||
local compform=$(echo "$opt" | cut -f 2- -d '=')
|
local compform=$2
|
||||||
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"-p"?*|"--parallel"?*)
|
-p|--parallel)
|
||||||
local nproc=$(echo "$opt" | cut -f 2- -d '=')
|
local nproc=$2
|
||||||
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"-v"|"--verbose")
|
-v|--verbose)
|
||||||
local verbose=1
|
local verbose=1
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"-q"|"--quiet")
|
-q|--quiet)
|
||||||
QUIET=1
|
local quiet=1
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"-"*)
|
-[1-9])
|
||||||
local complevel=$(echo $opt | sed 's/-//')
|
compression="${1#-}"
|
||||||
if ! [[ $complevel =~ ^[1-9]+$ ]]; then
|
shift
|
||||||
disp E "Invalid option, use taz --help to display options list"
|
;;
|
||||||
echo
|
--)
|
||||||
return 1
|
shift
|
||||||
fi
|
break
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
local LIST="$LIST ${opt%/}"
|
disp E "Invalid option, use \"taz --help\" to display options list"
|
||||||
|
return 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# The remaining arguments after -- are the files/directories to process,
|
||||||
|
# "." is used if none is given
|
||||||
|
local FILES=("$@")
|
||||||
|
[[ ${#FILES[@]} -eq 0 ]] && FILES=(".")
|
||||||
|
|
||||||
[[ ! $compform ]] && compform=lz # safe and efficient (unless data are already compressed)
|
[[ ! $compform ]] && compform=lz # safe and efficient (unless data are already compressed)
|
||||||
[[ ! $nproc ]] && nproc=1
|
[[ ! $nproc ]] && nproc=1
|
||||||
[[ ! $complevel ]] && complevel=6
|
[[ ! $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."
|
disp E "The --verbose and --quiet options can't be used together."
|
||||||
|
|
||||||
for item in $LIST; do
|
for item in "${FILES[@]}"; do
|
||||||
local donetar=0
|
local donetar=0
|
||||||
disp I "Processing $item..."
|
disp I "Processing $item..."
|
||||||
|
|
||||||
if [[ -d $item ]]; then
|
if [[ -d "$item" ]]; then
|
||||||
disp I "\t Creating $item.tar... "
|
disp I "\t Creating $item.tar... "
|
||||||
|
|
||||||
tar -cf $item{.tar,}
|
tar -cf "$item.tar" "$item"
|
||||||
if [[ ! $? -eq 0 ]]; then
|
if [[ ! $? -eq 0 ]]; then
|
||||||
disp E "tar file creation failed, skipping to next item."
|
disp E "tar file creation failed, skipping to next item."
|
||||||
continue
|
continue
|
||||||
@@ -336,7 +593,7 @@ taz ()
|
|||||||
# Skip compression part if tar is asked
|
# Skip compression part if tar is asked
|
||||||
if [[ $compform != "tar" ]]; then
|
if [[ $compform != "tar" ]]; then
|
||||||
disp I "\t Compressing archive..."
|
disp I "\t Compressing archive..."
|
||||||
_do$compform $fname $nproc $complevel $verbose
|
_do$compform "$fname" "$nproc" "$complevel" "$verbose"
|
||||||
[[ ! $? -eq 0 ]] && case $? in
|
[[ ! $? -eq 0 ]] && case $? in
|
||||||
127)
|
127)
|
||||||
disp E "Compression program unavailable, aborting."
|
disp E "Compression program unavailable, aborting."
|
||||||
@@ -348,14 +605,18 @@ taz ()
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
[[ $donetar -gt 0 ]] && rm $fname
|
[[ $donetar -gt 0 ]] && rm "$fname"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $willrm ]]; then
|
if [[ $willrm ]]; then
|
||||||
disp I "\t Deleting original source as asked... "
|
disp I "\t Deleting original source as asked... "
|
||||||
rm -r $item
|
rm -r "$item"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
unset QUIET
|
unset quiet
|
||||||
}
|
}
|
||||||
export -f taz
|
export -f taz
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,27 +36,22 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Display a backtrace
|
# Display a backtrace
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: backtrace
|
||||||
function backtrace()
|
function backtrace()
|
||||||
{
|
{
|
||||||
echo "========= Call stack ========="
|
printf "========= Call stack =========\n"
|
||||||
typeset -i i=0
|
local i=1 # We begin at 1 to ignore backtrace itself
|
||||||
|
while [[ $i -lt ${#FUNCNAME[@]} ]]; do
|
||||||
local func=
|
|
||||||
for func in "${FUNCNAME[@]}"; do
|
|
||||||
if [[ $i -ne 0 ]]; then
|
|
||||||
printf '%15s() %s:%d\n' \
|
printf '%15s() %s:%d\n' \
|
||||||
"$func" "${BASH_SOURCE[$i]}" "${BASH_LINENO[ (( $i - 1)) ]}"
|
"${FUNCNAME[$i]}" "${BASH_SOURCE[$i]}" "${BASH_LINENO[$(( i-1 ))]}"
|
||||||
fi
|
((i++))
|
||||||
let i++ || true
|
|
||||||
done
|
done
|
||||||
unset func i
|
unset i
|
||||||
echo "=============================="
|
printf "==============================\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Function to be trapped for errors investigation
|
# Function to be trapped for errors investigation
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
function error()
|
function error()
|
||||||
{
|
{
|
||||||
local errcode=$?
|
local errcode=$?
|
||||||
@@ -63,45 +59,72 @@ function error ()
|
|||||||
return $errcode
|
return $errcode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Activate or deactivate error trapping to display backtrace
|
# Activate or deactivate error trapping to display backtrace
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: settrace <--on|--off|--status>
|
||||||
settrace()
|
settrace()
|
||||||
{
|
{
|
||||||
local status="off"
|
local status="off"
|
||||||
[[ $(trap -p ERR) ]] && status="on"
|
[[ $(trap -p ERR) ]] && status="on"
|
||||||
#trap -p ERR
|
#trap -p ERR
|
||||||
for opt in $@ ; do
|
|
||||||
case $opt in
|
local PARSED
|
||||||
"-h"|"--help")
|
PARSED=$(getopt -oh --long help,on,off,status,force -- "$@")
|
||||||
echo "Try to activate backtrace display for script debugging."
|
if [[ $? -ne 0 ]]; then
|
||||||
echo
|
disp E "Invalid options, use \"settrace --help\" to display usage."
|
||||||
echo "Options:"
|
return 1
|
||||||
echo " --on Activate backtrace generation"
|
fi
|
||||||
echo " --off Deactivate backtrace generation"
|
eval set -- "$PARSED"
|
||||||
echo
|
local force=0
|
||||||
echo "That function active a trap event on error. If the script you want to"
|
while true; do
|
||||||
echo "debug overload the ERR bash trap, it will not work."
|
case $1 in
|
||||||
echo
|
-h|--help)
|
||||||
|
printf "Try to activate backtrace display for script debugging.\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t--on\t\tActivate backtrace generation\n"
|
||||||
|
printf "\t--force\t\tForce replacement of existing trap (use with --on)\n"
|
||||||
|
printf "\t--off\t\tDeactivate backtrace generation\n\n"
|
||||||
|
printf "That function active a trap event on error. If the script you want to\n"
|
||||||
|
printf "debug overload the ERR bash trap, it will not work.\n"
|
||||||
|
return 0
|
||||||
;;
|
;;
|
||||||
"--on")
|
--on)
|
||||||
if [[ $status == "on" ]]; then
|
if [[ ${status} == "on" ]] && [[ $force -eq 0 ]]; then
|
||||||
disp W "ERR signal trap is already set, replacing previous trap!"
|
disp E "ERR signal trap is already set. Use --force to replace it."
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
trap "error" ERR
|
trap "error" ERR
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
"--off")
|
--force)
|
||||||
if [[ $status != "on" ]]; then
|
force=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--off)
|
||||||
|
if [[ ${status} != "on" ]]; then
|
||||||
disp W "ERR signal trap is already unset!"
|
disp W "ERR signal trap is already unset!"
|
||||||
fi
|
fi
|
||||||
trap - ERR
|
trap - ERR
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
"--status")
|
--status)
|
||||||
disp "ERR trap signal is ${status}."
|
disp I "Trap signal is ${status}."
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid options, use \"settrace --help\" to display usage."
|
||||||
|
return 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
unset status
|
unset status force
|
||||||
}
|
}
|
||||||
export -f settrace
|
export -f settrace
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,11 +36,11 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Color definitions
|
# Color definitions
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# Standard 16 colors display declaration
|
# Standard 16 colors display declaration
|
||||||
export DEFAULTFG="\e[0;39m"
|
export DEFAULTFG='\e[0;39m'
|
||||||
export DEFAULTBG="\e[0;49m"
|
export DEFAULTBG='\e[0;49m'
|
||||||
export DEFAULTCOL=${DEFAULTBG}${DEFAULTFG}
|
export DEFAULTCOL="${DEFAULTBG}${DEFAULTFG}"
|
||||||
|
export RESETCOL=$'\e[0m'
|
||||||
|
|
||||||
# Regular Colors
|
# Regular Colors
|
||||||
export Black='\e[0;30m'
|
export Black='\e[0;30m'
|
||||||
@@ -110,39 +111,73 @@ export On_IBlue='\e[0;104m'
|
|||||||
export On_IPurple='\e[0;105m'
|
export On_IPurple='\e[0;105m'
|
||||||
export On_ICyan='\e[0;106m'
|
export On_ICyan='\e[0;106m'
|
||||||
export On_IWhite='\e[0;107m'
|
export On_IWhite='\e[0;107m'
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Display a message
|
# Display a message
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: disp <type> <message>
|
||||||
|
# Types:
|
||||||
|
# I : info (green)
|
||||||
|
# W : warning (yellow)
|
||||||
|
# E : error (red)
|
||||||
|
# D : debug (cyan)
|
||||||
disp()
|
disp()
|
||||||
{
|
{
|
||||||
case $1 in
|
# Handle NO_COLOR: disable colors if set
|
||||||
|
local color_enabled=1
|
||||||
|
[[ -n $NO_COLOR ]] && color_enabled=0
|
||||||
|
|
||||||
|
case ${1^^} in
|
||||||
"I")
|
"I")
|
||||||
|
if [[ $color_enabled -eq 1 ]]; then
|
||||||
local heads="[ ${IGreen}info${DEFAULTFG} ]"
|
local heads="[ ${IGreen}info${DEFAULTFG} ]"
|
||||||
|
else
|
||||||
|
local heads="[ info ]"
|
||||||
|
fi
|
||||||
shift
|
shift
|
||||||
[[ -z $QUIET || $QUIET -ne 1 ]] && echo -e "${heads} $@"
|
[[ -z $QUIET || $QUIET -ne 1 ]] && \
|
||||||
|
printf "%b\n" "${heads} $*${RESETCOL}"
|
||||||
;;
|
;;
|
||||||
"W")
|
"W")
|
||||||
|
if [[ $color_enabled -eq 1 ]]; then
|
||||||
local heads="[ ${IYellow}Warning${DEFAULTFG} ]"
|
local heads="[ ${IYellow}Warning${DEFAULTFG} ]"
|
||||||
|
else
|
||||||
|
local heads="[ Warning ]"
|
||||||
|
fi
|
||||||
shift
|
shift
|
||||||
echo -e "${heads} $@" >&2
|
printf "%b\n" "${heads} $*${RESETCOL}" >&2
|
||||||
;;
|
;;
|
||||||
"E")
|
"E")
|
||||||
|
if [[ $color_enabled -eq 1 ]]; then
|
||||||
local heads="[ ${IRed}ERROR${DEFAULTFG} ]"
|
local heads="[ ${IRed}ERROR${DEFAULTFG} ]"
|
||||||
|
else
|
||||||
|
local heads="[ ERROR ]"
|
||||||
|
fi
|
||||||
shift
|
shift
|
||||||
echo -e "${heads} $@" >&2
|
printf "%b\n" "${heads} $*${RESETCOL}" >&2
|
||||||
;;
|
;;
|
||||||
"D")
|
"D")
|
||||||
local heads"[ ${ICyan}debug${DEFAULTFG} ]"
|
if [[ $color_enabled -eq 1 ]]; then
|
||||||
|
local heads="[ ${ICyan}debug${DEFAULTFG} ]"
|
||||||
|
else
|
||||||
|
local heads="[ debug ]"
|
||||||
|
fi
|
||||||
shift
|
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 ]] && \
|
||||||
[[ -z $QUIET || $QUIET -ne 1 ]] && echo -e "$@"
|
printf "%b\n" "$*"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
unset heads
|
|
||||||
}
|
}
|
||||||
export -f disp
|
export -f disp
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# Load disp section variables
|
||||||
|
load_conf disp
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -34,181 +35,761 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# expandlist : treat wildcards in a file/directory list
|
# Expand wildcards in a file/directory list and quote the results
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: expandlist [options] <item1 [item2 ... itemN]>
|
||||||
expandlist()
|
expandlist()
|
||||||
{
|
{
|
||||||
local result=""
|
local separator=" "
|
||||||
for item in "$1"; do
|
local PARSED
|
||||||
for content in "$item"; do
|
|
||||||
result+="\"$content\" "
|
|
||||||
done
|
|
||||||
done
|
|
||||||
echo $result
|
|
||||||
}
|
|
||||||
|
|
||||||
|
PARSED=$(getopt -o hs:n --long help,separator:,newline -n 'expandlist' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"expandlist --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
while true; do
|
||||||
# Clean a directory or a tree from temporary or backup files
|
case "$1" in
|
||||||
# ------------------------------------------------------------------------------
|
-h|--help)
|
||||||
clean ()
|
printf "expandlist: expand globs and wrap matched items in double quotes.\n\n"
|
||||||
{
|
printf "Usage: expandlist [options] <item1 [item2 ... itemN]>\n\n"
|
||||||
for opt in $@ ; do
|
printf "Options:\n"
|
||||||
case $opt in
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
"-r"|"--recurs")
|
printf "\t-s, --separator SEP\tSet output separator (default: space)\n"
|
||||||
local recursive=1
|
printf "\t-n, --newline\t\tUse a newline as separator\n"
|
||||||
;;
|
|
||||||
|
|
||||||
"-h"|"--help")
|
|
||||||
echo "clean: erase backup files in the given directories."
|
|
||||||
echo
|
|
||||||
echo "Usage: clean [option] [directory1] [...[directoryX]]"
|
|
||||||
echo
|
|
||||||
echo "Options:"
|
|
||||||
echo " -h, --help Display that help screen"
|
|
||||||
echo " -r, --recurs Do a recursive cleaning"
|
|
||||||
echo " -f, --force Do not ask for confirmation (use with care)"
|
|
||||||
echo " -s, --shell Do nothing and display what will be executed"
|
|
||||||
echo
|
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
-s|--separator)
|
||||||
"-s"|"--shell")
|
separator="$2"
|
||||||
local outshell=1
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
-n|--newline)
|
||||||
"-f"|"--force")
|
separator=$'\n'
|
||||||
local force=1
|
shift
|
||||||
;;
|
;;
|
||||||
|
--)
|
||||||
"-"*)
|
shift
|
||||||
disp E "Invalid option, use \"clean --help\" to display usage."
|
break
|
||||||
echo
|
|
||||||
return 1
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
local dirlist="$dirlist $opt"
|
disp E "Invalid options, use \"expandlist --help\" to display usage."
|
||||||
|
return 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ ! $dirlist ]] && local dirlist=$(pwd)
|
local item="" result="" matched=0
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
[[ ! $recursive ]] && local findopt="-maxdepth 1"
|
for item in "$@"; do
|
||||||
[[ ! $force ]] && local rmopt="-i"
|
local expanded=()
|
||||||
unset recursive force
|
|
||||||
|
|
||||||
for dir in $dirlist; do
|
# True glob expansion when wildcards are present.
|
||||||
local dellist=$(find $dir $findopt -type f -name "*~" -o -name "#*#" \
|
if [[ "$item" == *'*'* || "$item" == *'?'* || "$item" == *'['* ]]; then
|
||||||
-o -name "*.bak" -o -name ".~*#")
|
expanded=( $item )
|
||||||
for f in $dellist; do
|
|
||||||
if [[ ! $outshell ]]; then
|
|
||||||
rm $rmopt $f
|
|
||||||
else
|
else
|
||||||
echo "rm $rmopt $f"
|
expanded=( "$item" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${#expanded[@]} -eq 0 ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
for content in "${expanded[@]}"; do
|
||||||
|
if (( matched )); then
|
||||||
|
result+="$separator"
|
||||||
|
fi
|
||||||
|
result+="\"$content\""
|
||||||
|
matched=1
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
shopt -u nullglob
|
||||||
|
printf '%s\n' "$result"
|
||||||
|
}
|
||||||
|
export -f expandlist
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Clean a directory tree from temporary or backup files
|
||||||
|
# Usage: clean [options] [directory1] [...[directoryX]]
|
||||||
|
# Options:
|
||||||
|
# -h, --help: display help screen
|
||||||
|
# -r, --recurs: do a recursive cleaning
|
||||||
|
# -f, --force: do not ask for confirmation (use with care)
|
||||||
|
# -s, --shell: do nothing and display what will be executed
|
||||||
|
clean()
|
||||||
|
{
|
||||||
|
local recursive=0 force=0 outshell=0
|
||||||
|
|
||||||
|
# Define short and long options
|
||||||
|
local PARSED
|
||||||
|
PARSED=$(getopt -o hrsf --long help,recurs,shell,force -n 'clean' -- "$@")
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"clean --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-r|--recurs)
|
||||||
|
recursive=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
printf "clean: erase backup files in the given directories.\n\n"
|
||||||
|
printf "Usage: clean [option] [directory1] [...[directoryX]]\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay that help screen\n"
|
||||||
|
printf "\t-r, --recurs\t\tDo a recursive cleaning\n"
|
||||||
|
printf "\t-f, --force\t\tDo not ask for confirmation (use with care)\n"
|
||||||
|
printf "\t-s, --shell\t\tDo nothing and display what will be executed\n"
|
||||||
|
printf "\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-s|--shell)
|
||||||
|
outshell=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-f|--force)
|
||||||
|
force=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid parameter, use \"clean --help\" to display options list"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Handle remaining arguments as directories
|
||||||
|
local dirlist=("$@")
|
||||||
|
[[ ${#dirlist[@]} -eq 0 ]] && dirlist=(".")
|
||||||
|
|
||||||
|
local findopt=() rmopt=()
|
||||||
|
(( ! recursive )) && findopt=(-maxdepth 1)
|
||||||
|
(( ! force )) && rmopt=(-i)
|
||||||
|
|
||||||
|
for dir in "${dirlist[@]}"; do
|
||||||
|
find "$dir" "${findopt[@]}" -type f \( -name "*~" -o -name "#*#" -o -name "*.bak" -o -name ".~*#" \) -print0 |
|
||||||
|
while IFS= read -r -d '' f; do
|
||||||
|
if (( outshell )); then
|
||||||
|
if (( ${#rmopt[@]} )); then
|
||||||
|
printf 'rm %s -- "%s"\n' "${rmopt[*]}" "$f"
|
||||||
|
else
|
||||||
|
printf 'rm -- "%s"\n' "$f"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
rm "${rmopt[@]}" -- "$f"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
unset outshell dirlist dellist findopt rmopt
|
|
||||||
}
|
}
|
||||||
export -f clean
|
export -f clean
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Create a directory then goes inside
|
# Create a directory then goes inside
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: mcd <directory>
|
||||||
mcd()
|
mcd()
|
||||||
{
|
{
|
||||||
|
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||||
|
printf "mcd: Create a directory and enter it.\n\n"
|
||||||
|
printf "Usage: mcd <directory>\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ! $# -eq 1 ]]; then
|
if [[ ! $# -eq 1 ]]; then
|
||||||
disp E "Create a directory then goes inside."
|
disp E "Missing parameter. Use \"mcd --help\" to display usage."
|
||||||
disp E "Usage: mcd <directory>"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
mkdir -pv $1 && cd $1
|
mkdir -pv "$1" && cd "$1" || {
|
||||||
|
printf "Failed create and/or change directory.\n"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export -f mcd
|
export -f mcd
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Rename all files in current directory to replace spaces with _
|
# Rename files and directories to replace spaces with another character
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: rmspc [options]
|
||||||
|
# Options:
|
||||||
|
# -h, --help: display help screen
|
||||||
|
# -r, --recursive: treat subdirectories of the given directory
|
||||||
|
# -c, --subst-char: change the replacement character (default is underscore)
|
||||||
|
# -v, --verbose: display more details (recursive mode only)
|
||||||
|
# -s, --shell: do nothing and display commands that would be executed
|
||||||
rmspc()
|
rmspc()
|
||||||
{
|
{
|
||||||
local lst=""
|
local recurs=0 verb=0 shell=0
|
||||||
for opt in $@ ; do
|
local substchar="_" substchar_set=0
|
||||||
case $opt in
|
local mvopt=()
|
||||||
"-h"|"--help")
|
local PARSED
|
||||||
echo "rmspc: remove spaces from all filenames in current directories"
|
|
||||||
echo
|
PARSED=$(getopt -o hr:c::vs --long help,recursive,subst-char::,verbose,shell -n 'rmspc' -- "$@")
|
||||||
echo "Usage: rmspc [option]"
|
if [[ $? -ne 0 ]]; then
|
||||||
echo
|
disp E "Invalid options, use \"rmspc --help\" to display usage."
|
||||||
echo "Options:"
|
return 1
|
||||||
echo " -h, --help Display that help screen"
|
fi
|
||||||
echo " -r, --recursive Treat subdirectories of the given directory"
|
eval set -- "$PARSED"
|
||||||
echo " -c, --subst-char Change the replacement character (default is underscore)"
|
|
||||||
echo " -v, --verbose Display more details (recursive mode only)"
|
while true; do
|
||||||
echo " -s, --shell Do nothing and display commands that would be executed"
|
case "$1" in
|
||||||
echo
|
-h|--help)
|
||||||
echo "Note: if the --subst-char option is given without parameters, spaces will be"
|
printf "rmspc: remove spaces from all filenames in current directories\n\n"
|
||||||
echo " replaced with nothing (concatenation)."
|
printf "Usage: rmspc [option]\n\n"
|
||||||
echo
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay that help screen\n"
|
||||||
|
printf "\t-r, --recursive\t\tTreat subdirectories of the given directory\n"
|
||||||
|
printf "\t-c, --subst-char\tChange the replacement character (default is underscore)\n"
|
||||||
|
printf "\t-v, --verbose\t\tDisplay more details (recursive mode only)\n"
|
||||||
|
printf "\t-s, --shell\t\tDo nothing and display commands that would be executed\n\n"
|
||||||
|
printf "Note: if the --subst-char option is given without parameters, spaces will be\n"
|
||||||
|
printf " replaced with nothing (concatenation).\n"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
-r|--recursive)
|
||||||
"-r"|"--recursive")
|
recurs=1
|
||||||
local recurs=1
|
shift
|
||||||
;;
|
;;
|
||||||
|
-c|--subst-char)
|
||||||
"-c"?*|"--subst-char"?*)
|
substchar_set=1
|
||||||
if [[ $(echo $opt | grep "=") ]]; then
|
substchar="$2"
|
||||||
local substchar=$(echo "$opt" | cut -f 2- -d '=')
|
shift 2
|
||||||
else
|
|
||||||
local substchar='none'
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
|
-v|--verbose)
|
||||||
"-v"|"--verbose")
|
verb=1
|
||||||
local verb=1
|
shift
|
||||||
;;
|
;;
|
||||||
|
-s|--shell)
|
||||||
"-s"|"--shell")
|
shell=1
|
||||||
local shell=1
|
shift
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
disp E "Invalid parameter, use \"rmspc --help\" to display options list"
|
disp E "Invalid parameter, use \"rmspc --help\" to display options list"
|
||||||
echo
|
|
||||||
return 1
|
return 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ ! $substchar ]] && substchar="_"
|
[[ "$substchar" == "none" ]] && substchar=""
|
||||||
[[ $substchar == "none" ]] && local substchar=""
|
(( verb )) && mvopt=(-v)
|
||||||
[[ $verb ]] && local mvopt="-v"
|
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
for f in *; do
|
for f in *; do
|
||||||
[[ $recurs ]] && [[ -d "$f" ]] && (
|
if (( recurs )) && [[ -d "$f" ]]; then
|
||||||
[[ $verb ]] && disp I "Entering directory $(pwd)/$f ..."
|
(
|
||||||
local lastdir=$f
|
local lastdir=$f
|
||||||
pushd "$f" > /dev/null
|
(( verb )) && disp I "Entering directory $(pwd)/$f ..."
|
||||||
rmspc $@
|
pushd "$f" >/dev/null || exit 1
|
||||||
popd > /dev/null
|
|
||||||
[[ $verb ]] && disp I "Leaving directory $(pwd)/$lastdir"
|
|
||||||
unset lastdir
|
|
||||||
)
|
|
||||||
|
|
||||||
if [[ $(echo $f | grep " ") ]]; then
|
if (( substchar_set )); then
|
||||||
local newf="${f// /${substchar}}"
|
rmspc ${recurs:+-r} -c "$substchar" ${verb:+-v} ${shell:+-s}
|
||||||
local command="mv $mvopt \"$f\" \"$newf\""
|
|
||||||
if [[ $shell ]]; then
|
|
||||||
echo $command
|
|
||||||
else
|
else
|
||||||
$command
|
rmspc ${recurs:+-r} ${verb:+-v} ${shell:+-s}
|
||||||
|
fi
|
||||||
|
|
||||||
|
popd >/dev/null || exit 1
|
||||||
|
(( verb )) && disp I "Leaving directory $(pwd)/$lastdir"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$f" == *" "* ]]; then
|
||||||
|
local newf="${f// /${substchar}}"
|
||||||
|
[[ "$f" == "$newf" ]] && continue
|
||||||
|
if (( shell )); then
|
||||||
|
if (( ${#mvopt[@]} )); then
|
||||||
|
printf 'mv %s -- "%s" "%s"\n' "${mvopt[*]}" "$f" "$newf"
|
||||||
|
else
|
||||||
|
printf 'mv -- "%s" "%s"\n' "$f" "$newf"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
mv "${mvopt[@]}" -- "$f" "$newf" || {
|
||||||
|
disp E "Failed renaming \"$f\" to \"$newf\"."
|
||||||
|
continue
|
||||||
|
}
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
unset lst substchar verb shell newf command mvopt
|
shopt -u nullglob
|
||||||
}
|
}
|
||||||
export -f rmspc
|
export -f rmspc
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Display statistics about a file tree
|
||||||
|
# Usage: file_stats [options] [path]
|
||||||
|
# Options:
|
||||||
|
# -H, --human Human readable sizes\n"
|
||||||
|
# -d, --details Display details (min/max/average/median)
|
||||||
|
# -m, --average Display only average size
|
||||||
|
# -M, --median Display only median size
|
||||||
|
# -c, --count Display only count of files
|
||||||
|
# -t, --total Display only total size
|
||||||
|
# -a, --all Display all stats in human readable format (shortcut for -H -d)
|
||||||
|
# -x, --ext [ext] Filter by extension (e.g. -x log for .log files)
|
||||||
|
# -X, --ext-list [list] Filter by multiple extensions (e.g. -X log,txt)
|
||||||
|
# --min [size] Minimum size (e.g., 10M)
|
||||||
|
# --max [size] Maximum size (e.g., 100M)
|
||||||
|
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 PARSED
|
||||||
|
# Short: H, d, m, M, c, t, a, x:, X:
|
||||||
|
# Long: human, details, average, median, count, total, all, ext:, ext-list:, min:, max:, help
|
||||||
|
PARSED=$(getopt -o HdmMctax:X:h --long human,details,average,median,count,total,all,ext:,ext-list:,min:,max:,help -n 'file_stats' -- "$@")
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"file_stats --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "Usage: file_stats [options] [path]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-H, --human\t\tHuman readable sizes\n"
|
||||||
|
printf "\t-d, --details\t\tShow detailed histogram\n"
|
||||||
|
printf "\t-m, --average\t\tShow only average size\n"
|
||||||
|
printf "\t-M, --median\t\tShow only median size\n"
|
||||||
|
printf "\t-c, --count\t\tShow only file count\n"
|
||||||
|
printf "\t-t, --total\t\tShow only total size\n"
|
||||||
|
printf "\t-a, --all\t\tShow all (human + details)\n"
|
||||||
|
printf "\t-x, --ext [ext]\t\tFilter by extension\n"
|
||||||
|
printf "\t-X, --ext-list [list]\tFilter by comma-separated list\n"
|
||||||
|
printf "\t--min [size]\t\tMinimum size (e.g., 10M)\n"
|
||||||
|
printf "\t--max [size]\t\tMaximum size (e.g., 100M)\n"
|
||||||
|
return 0 ;;
|
||||||
|
-H|--human)
|
||||||
|
human=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-d|--details)
|
||||||
|
details=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-m|--average)
|
||||||
|
only_avg=1
|
||||||
|
show_all=0
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-M|--median)
|
||||||
|
only_med=1
|
||||||
|
show_all=0
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-c|--count)
|
||||||
|
only_count=1
|
||||||
|
show_all=0
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-t|--total)
|
||||||
|
only_total=1
|
||||||
|
show_all=0
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-a|--all)
|
||||||
|
human=1
|
||||||
|
details=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-x|--ext)
|
||||||
|
ext_filter="${2#.}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-X|--ext-list)
|
||||||
|
ext_list="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--min)
|
||||||
|
min_size="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--max)
|
||||||
|
max_size="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid option: $1"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ -n "$1" ]] && path="$1"
|
||||||
|
|
||||||
|
# Prepare find filters
|
||||||
|
local find_cmd=(find "$path" -type f)
|
||||||
|
|
||||||
|
# Single extension filter
|
||||||
|
if [[ -n "$ext_filter" ]]; then
|
||||||
|
find_cmd+=(-iname "*.$ext_filter")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extension list filter
|
||||||
|
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
|
||||||
|
|
||||||
|
# Minimum/maximum size filters (evaluated in bytes)
|
||||||
|
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
|
||||||
|
|
||||||
|
# Execution
|
||||||
|
"${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" '
|
||||||
|
# Convert function
|
||||||
|
function human_readable(x) {
|
||||||
|
split("B KiB MiB GiB TiB", units)
|
||||||
|
i = 1
|
||||||
|
while (x >= 1024 && i < 5) {
|
||||||
|
x /= 1024
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return sprintf("%.2f %s", x, units[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display function
|
||||||
|
function out(label, val, is_size) {
|
||||||
|
if (human == 1 && is_size == 1) val = human_readable(val)
|
||||||
|
printf "%-20s : %s\n", label, val
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
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 "No files found."
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
average = total / count
|
||||||
|
|
||||||
|
# Median calculation: exact using sorted array values
|
||||||
|
if (count % 2 == 1) {
|
||||||
|
median = sizes[(count + 1) / 2]
|
||||||
|
} else {
|
||||||
|
idx = count / 2
|
||||||
|
median = (sizes[idx] + sizes[idx + 1]) / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (only_avg) out("Average size", average, 1)
|
||||||
|
else if (only_med) out("Median size", median, 1)
|
||||||
|
else if (only_count) out("Number of files", count, 0)
|
||||||
|
else if (only_total) out("Total size", total, 1)
|
||||||
|
else {
|
||||||
|
if (show_all || human || details) {
|
||||||
|
printf "Statistics for \"%s\"\n", path
|
||||||
|
printf "-------------------------\n"
|
||||||
|
}
|
||||||
|
out("Number of files", count, 0)
|
||||||
|
out("Total size", total, 1)
|
||||||
|
out("Average size", average, 1)
|
||||||
|
out("Median size", median, 1)
|
||||||
|
out("Minimum size", min, 1)
|
||||||
|
out("Maximum size", max, 1)
|
||||||
|
}
|
||||||
|
if (details) {
|
||||||
|
print "\nSize histogram:"
|
||||||
|
|
||||||
|
# Use a separate array for the loop to avoid collision
|
||||||
|
for (b in bucket) {
|
||||||
|
# Pre-calculate label parts
|
||||||
|
# 1024^0 = 1 (B), 1024^1 = 1K, etc.
|
||||||
|
low = (b == 0) ? 0 : (1024^b)
|
||||||
|
high = 1024^(b+1)
|
||||||
|
|
||||||
|
label = sprintf("%-9s – %-9s",
|
||||||
|
(b == 0) ? "0" : human_readable(low),
|
||||||
|
human_readable(high))
|
||||||
|
|
||||||
|
# We store buckets in an array, access them by index b
|
||||||
|
printf "%-25s : %6d fichiers\n", label, bucket[b]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
}
|
||||||
|
export -f file_stats
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Find the biggest files in a directory tree
|
||||||
|
# Usage: findbig [options] [directory]
|
||||||
|
# Options:
|
||||||
|
# -h : display help screen
|
||||||
|
# -d : display details (ls -l) for each file
|
||||||
|
# -x : do not cross filesystem boundaries
|
||||||
|
# -l : limit : number of files to return (default is 10)
|
||||||
|
findbig()
|
||||||
|
{
|
||||||
|
local details=0 limit=10 one_fs=0
|
||||||
|
|
||||||
|
local PARSED
|
||||||
|
PARSED=$(getopt -o hdl:x --long help,details,limit:,one-fs -n 'findbig' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"findbig --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "findbig: Find the N biggest files in a directory tree.\n\n"
|
||||||
|
printf "Usage: findbig [options] [directory]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
printf "\t-d, --details\t\tShow detailed file info (ls -ld)\n"
|
||||||
|
printf "\t-l, --limit N\t\tNumber of files to return (default: 10)\n"
|
||||||
|
printf "\t-x, --one-fs\t\tDo not cross filesystem boundaries\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-d|--details)
|
||||||
|
details=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-l|--limit)
|
||||||
|
limit="$2"
|
||||||
|
[[ "$limit" =~ ^[0-9]+$ ]] || {
|
||||||
|
disp E "Invalid limit: must be a positive integer."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-x|--one-fs)
|
||||||
|
one_fs=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid option: $1"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
local dir="${1:-.}"
|
||||||
|
|
||||||
|
# Prepare find arguments in an array for cleaner handling
|
||||||
|
local find_args=(-L "$dir")
|
||||||
|
(( one_fs )) && find_args+=(-xdev)
|
||||||
|
find_args+=(-type f)
|
||||||
|
|
||||||
|
# Logic: find files, print size and path, sort numeric reverse, take N
|
||||||
|
if (( details )); then
|
||||||
|
find "${find_args[@]}" -printf "%s %p\n" 2>/dev/null | sort -rn | head -n "$limit" |
|
||||||
|
while IFS= read -r line; do
|
||||||
|
local path="${line#* }"
|
||||||
|
ls -ld -- "$path"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
find "${find_args[@]}" -printf "%s %p\n" 2>/dev/null | sort -rn | head -n "$limit"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
export -f findbig
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Find empty files in a directory tree
|
||||||
|
# Usage: findzero [options] [directory]
|
||||||
|
# Options:
|
||||||
|
# -h : display help screen
|
||||||
|
# -d : display details (ls -l) for each file
|
||||||
|
# -x : do not cross filesystem boundaries
|
||||||
|
# --delete : delete empty files and display their paths
|
||||||
|
findzero()
|
||||||
|
{
|
||||||
|
local delete=0 details=0 one_fs=0
|
||||||
|
|
||||||
|
local PARSED
|
||||||
|
# o: options, long: long equivalents
|
||||||
|
PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'findzero' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"findzero --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "findzero: Find or delete empty files in a directory tree.\n\n"
|
||||||
|
printf "Usage: findzero [options] [directory]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
printf "\t-d, --details\t\tShow detailed file info (ls -ls)\n"
|
||||||
|
printf "\t-x, --one-fs\t\tDo not cross filesystem boundaries\n"
|
||||||
|
printf "\t--delete\t\tActually remove the empty files\n"
|
||||||
|
return 0 ;;
|
||||||
|
-d|--details)
|
||||||
|
details=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-x|--one-fs)
|
||||||
|
one_fs=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--delete)
|
||||||
|
delete=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid option: $1"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
local dir="${1:-.}"
|
||||||
|
local find_args=("-L" "$dir" "-type" "f" "-empty")
|
||||||
|
|
||||||
|
(( one_fs )) && find_args+=("-xdev")
|
||||||
|
|
||||||
|
# Execution logic
|
||||||
|
if (( delete )); then
|
||||||
|
disp W "Deleting empty files in $dir..."
|
||||||
|
find "${find_args[@]}" -delete -print
|
||||||
|
elif (( details )); then
|
||||||
|
find "${find_args[@]}" -ls
|
||||||
|
else
|
||||||
|
find "${find_args[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
export -f findzero
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Find dead symbolic links in a directory tree
|
||||||
|
# Usage: finddead [options] [directory]
|
||||||
|
# Options:
|
||||||
|
# -h : display help screen
|
||||||
|
# -d : display details (ls -l) for each link
|
||||||
|
# -x : do not cross filesystem boundaries
|
||||||
|
# --delete : delete dead links and display their paths
|
||||||
|
finddead()
|
||||||
|
{
|
||||||
|
local delete=0 details=0 one_fs=0
|
||||||
|
|
||||||
|
local PARSED
|
||||||
|
PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'finddead' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"finddead --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "finddead: Find or delete dead/broken symbolic links.\n\n"
|
||||||
|
printf "Usage: finddead [options] [directory]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
printf "\t-d, --details\t\tShow detailed symlink info (ls -ls)\n"
|
||||||
|
printf "\t-x, --one-fs\t\tDo not cross filesystem boundaries\n"
|
||||||
|
printf "\t--delete\t\tActually remove the dead links\n"
|
||||||
|
return 0 ;;
|
||||||
|
-d|--details)
|
||||||
|
details=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-x|--one-fs)
|
||||||
|
one_fs=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--delete)
|
||||||
|
delete=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid option: $1"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
local dir="${1:-.}"
|
||||||
|
# -xtype l searches for links that do not point to an existing file
|
||||||
|
local find_args=("$dir" "-xtype" "l")
|
||||||
|
(( one_fs )) && find_args+=("-xdev")
|
||||||
|
|
||||||
|
# Execution logic
|
||||||
|
if (( delete )); then
|
||||||
|
disp W "Deleting dead symlinks in $dir..."
|
||||||
|
find "${find_args[@]}" -delete -print
|
||||||
|
elif (( details )); then
|
||||||
|
find "${find_args[@]}" -ls
|
||||||
|
else
|
||||||
|
find "${find_args[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
export -f finddead
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
112
profile.d/fun.sh
Normal file
112
profile.d/fun.sh
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright (c) 2013-2026 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
|
||||||
|
# Usage: busy [options] [pattern]
|
||||||
|
# Options:
|
||||||
|
# --delay=<ms> : add a delay between each line output (milliseconds)
|
||||||
|
# pattern : the string to search for in the hexdump output (default is "ca fe")
|
||||||
|
busy()
|
||||||
|
{
|
||||||
|
local pattern="ca fe" delay_ms=0
|
||||||
|
|
||||||
|
local PARSED
|
||||||
|
# Short: h, p:, d:
|
||||||
|
# Long: help, pattern:, delay:
|
||||||
|
PARSED=$(getopt -o hp:d: --long help,pattern:,delay: -n 'busy' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"busy --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "busy: Monitor /dev/urandom for a specific pattern.\n\n"
|
||||||
|
printf "Usage: busy [options] [pattern]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
printf "\t-p, --pattern PATTERN\tHex pattern to search (default: \"ca fe\")\n"
|
||||||
|
printf "\t-d, --delay MS\t\tDelay between matches in milliseconds\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-p|--pattern)
|
||||||
|
pattern="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-d|--delay)
|
||||||
|
delay_ms="$2"
|
||||||
|
if ! [[ "$delay_ms" =~ ^[0-9]+$ ]]; then
|
||||||
|
disp E "Invalid delay: must be an integer (milliseconds)."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid option: $1"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Convert milliseconds to seconds for 'sleep'
|
||||||
|
local delay_s=$(awk "BEGIN{
|
||||||
|
printf \"%.3f\", $delay_ms / 1000 }")
|
||||||
|
|
||||||
|
# Monitor /dev/urandom
|
||||||
|
(
|
||||||
|
hexdump -C < /dev/urandom | grep -iF --line-buffered "$pattern" | \
|
||||||
|
while read -r line; do
|
||||||
|
echo "$line"
|
||||||
|
[[ $delay_ms -gt 0 ]] && sleep "$delay_s"
|
||||||
|
done
|
||||||
|
) & local sub_pid=$!
|
||||||
|
|
||||||
|
IFS= read -r -n 1 -s _ </dev/tty
|
||||||
|
kill -- -"$sub_pid" 2>/dev/null || kill "$sub_pid" 2>/dev/null
|
||||||
|
wait "$sub_pid" 2>/dev/null
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,34 +36,52 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Display list of commands and general informations
|
# Display list of commands and general informations
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: help
|
||||||
help()
|
help()
|
||||||
{
|
{
|
||||||
cat <<EOF
|
printf "${BIWhite}Welcome to your profile! Here is a list of available commands:${DEFAULTCOL}\n\n"
|
||||||
clean Erase backup files
|
printf "check_updates\tCheck for new versions of profile\n"
|
||||||
dpkgs Search for the given package in the installed ones
|
printf "clean\t\tErase backup files\n"
|
||||||
gpid Give the list of PIDs for the given process name
|
printf "disp\t\tDisplay formatted info/warning/error/debug messages\n"
|
||||||
isipv4 Tell if the given IPv4 is valid
|
printf "dwl\t\tDownload a URL to a local file\n"
|
||||||
isipv6 Tell if the given IPv6 is valid
|
printf "expandlist\tExpand and quote item lists\n"
|
||||||
ku Kill process owned by users in parameter
|
printf "file_stats\tDisplay file size statistics for a path\n"
|
||||||
mcd Create a directory and go inside
|
printf "findbig\t\tFind biggest files in the given (or current) directory\n"
|
||||||
meteo Display curent weather forecast for the configured city
|
printf "finddead\tFind dead symbolic links in the given (or current) directory\n"
|
||||||
ppg Display process matching the given parameter
|
printf "findzero\tFind empty files in the given (or current) directory\n"
|
||||||
rain Let the rain fall
|
printf "genpwd\t\tGenerate secure passwords\n"
|
||||||
rmhost Remove host (IP and/or DNS name) for current known_host
|
printf "gpid\t\tGive the list of PIDs for the given process name\n"
|
||||||
rmspc Remove spaces from all the files in working directory
|
printf "isipv4\t\tTell if the given IPv4 is valid\n"
|
||||||
setc Set console language to C
|
printf "isipv6\t\tTell if the given IPv6 is valid\n"
|
||||||
setfr Set console language to French
|
printf "ku\t\tKill process owned by users in parameter\n"
|
||||||
settrace Activate/deactivate call trace for script debugging
|
printf "matrix\t\tDisplay matrix-style digital rain\n"
|
||||||
setus Set console language to US English
|
printf "mcd\t\tCreate a directory and go inside\n"
|
||||||
showinfo Show the welcoming baner with basic system information
|
printf "meteo\t\tDisplay current weather forecast for the configured city\n"
|
||||||
ssr Do a root login to the given address
|
printf "myextip\tDisplay current external/public IP\n"
|
||||||
taz Compress smartly the given files or directory
|
printf "pkgs\t\tSearch for the given package in installed ones\n"
|
||||||
utaz Uncompress all zip files in the given (or current) directory
|
printf "ppg\t\tDisplay process matching the given parameter\n"
|
||||||
ver Display version of your copy of profile
|
printf "ppn\t\tDisplay process matching the exact process name given in parameter\n"
|
||||||
|
printf "ppu\t\tDisplay processes owned by the given user\n"
|
||||||
|
printf "profile_upgrade\tUpgrade profile to the latest version\n"
|
||||||
|
printf "rain\t\tLet the rain fall\n"
|
||||||
|
printf "rmhost\t\tRemove host (IP and/or DNS name) from current known_hosts\n"
|
||||||
|
printf "rmspc\t\tRemove spaces from file and directory names\n"
|
||||||
|
printf "setlocale\tSet console language to the current locale\n"
|
||||||
|
printf " * setc\tSet console language to C\n"
|
||||||
|
printf " * setfr\tSet console language to French\n"
|
||||||
|
printf " * setus\tSet console language to US English\n"
|
||||||
|
printf "settrace\tActivate/deactivate call trace for script debugging\n"
|
||||||
|
printf "showinfo\tShow welcome banner with basic system information\n"
|
||||||
|
printf "ssr\t\tDo a root login to the given address\n"
|
||||||
|
printf "taz\t\tCompress smartly the given files or directory\n"
|
||||||
|
printf "urlencode\tURL-encode the given text\n"
|
||||||
|
printf "utaz\t\tUncompress archives in the given (or current) directory\n"
|
||||||
|
printf "ver\t\tDisplay version of your copy of profile\n\n"
|
||||||
|
|
||||||
Please use <command> --help to obtain usage details.
|
printf "\nPlease use <command> --help to obtain usage details.\n"
|
||||||
EOF
|
|
||||||
}
|
}
|
||||||
export -f help
|
export -f help
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,56 +36,144 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Show profile version
|
# Show profile version
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: ver
|
||||||
ver()
|
ver()
|
||||||
{
|
{
|
||||||
|
local PARSED=$(getopt -o h --long help -n 'ver' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"ver --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "ver: Display the current profile version.\nUsage: ver\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid options, use \"ver --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ -z $PROFVERSION ]] && \
|
||||||
|
disp W "No version defined. Profile is probably badly installed." && \
|
||||||
|
return 1
|
||||||
disp "Profile version $PROFVERSION."
|
disp "Profile version $PROFVERSION."
|
||||||
}
|
}
|
||||||
export -f ver
|
export -f ver
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Display weather of the given city (or default one)
|
# Display weather of the given city (or default one)
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: meteo [city1 city2 ...]
|
||||||
meteo()
|
meteo()
|
||||||
{
|
{
|
||||||
cities=$@
|
local PARSED=$(getopt -o h --long help -n 'meteo' -- "$@")
|
||||||
[[ $# -eq 0 ]] && local cities=$DEFAULT_CITY
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"meteo --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "meteo: Fetch weather data.\nUsage: meteo [city1 city2 ...]\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid options, use \"meteo --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
for city in $cities; do
|
local cities=("$@")
|
||||||
curl https://wttr.in/$city || disp E "Failed fetching datas for $city."
|
[[ $# -eq 0 ]] && cities=("$DEFAULT_CITY")
|
||||||
|
|
||||||
|
for city in "${cities[@]}"; do
|
||||||
|
encoded=$(urlencode "$city")
|
||||||
|
dwl "https://wttr.in/$encoded" || \
|
||||||
|
disp E "Failed fetching datas for $city."
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
export -f meteo
|
export -f meteo
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Display system general information
|
# Display system general information
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: showinfo
|
||||||
showinfo()
|
showinfo()
|
||||||
{
|
{
|
||||||
echo -e "\n"
|
local PARSED=$(getopt -o h --long help -n 'showinfo' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"showinfo --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "showinfo: Display system information (hostname, kernel, uptime).\nUsage: showinfo\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid options, use \"showinfo --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
printf "\n"
|
||||||
if command -v figlet >/dev/null 2>&1; then
|
if command -v figlet >/dev/null 2>&1; then
|
||||||
if [[ -s /usr/share/figlet/ansi_shadow.flf ]]; then
|
if [[ -s /usr/share/figlet/ansi_shadow.flf ]]; then
|
||||||
local figopt="-f ansi_shadow"
|
local figopt="-f ansi_shadow"
|
||||||
fi
|
fi
|
||||||
figlet -k $(hostname) $figopt
|
if [[ -n $figopt ]]; then
|
||||||
|
figlet -k $figopt $(hostname)
|
||||||
else
|
else
|
||||||
echo "$(hostname -f)"
|
figlet $(hostname)
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
hostname -f
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
if command -v neofetch >/dev/null 2>&1; then
|
if command -v neofetch >/dev/null 2>&1; then
|
||||||
neofetch
|
neofetch
|
||||||
|
elif command -v fastfetch >/dev/null 2>&1; then
|
||||||
|
fastfetch
|
||||||
else
|
else
|
||||||
(
|
(
|
||||||
if [[ -s /etc/os-release ]]; then
|
if [[ -s /etc/os-release ]]; then
|
||||||
|
# shellcheck disable=SC1091
|
||||||
. /etc/os-release
|
. /etc/os-release
|
||||||
echo "$NAME $VERSION"
|
printf "$NAME $VERSION\n"
|
||||||
else
|
else
|
||||||
cat /proc/version
|
cat /proc/version
|
||||||
fi
|
fi
|
||||||
echo "Uptime: $(uptime)"
|
printf "Uptime: $(uptime -p)\n"
|
||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
export -f showinfo
|
export -f showinfo
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
load_conf info
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -33,38 +34,148 @@
|
|||||||
# * OF SUCH DAMAGE.
|
# * OF SUCH DAMAGE.
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
locale_check()
|
||||||
# Change locale to French
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
setfr ()
|
|
||||||
{
|
{
|
||||||
# Set fr locale definitions
|
locale -a | grep -qx "$1" || {
|
||||||
export LANG=fr_FR.UTF-8
|
disp W "Locale '$1' is not installed on this system."
|
||||||
export LC_MESSAGES=fr_FR.UTF-8
|
return 1
|
||||||
export LC_ALL=fr_FR.UTF-8
|
|
||||||
}
|
}
|
||||||
export -f setfr
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Change locale to C standard
|
# Change locale to the given one in parameter
|
||||||
|
# Usage: setlocale <locale>
|
||||||
|
setlocale()
|
||||||
|
{
|
||||||
|
local PARSED
|
||||||
|
PARSED=$(getopt -o h --long help -n 'setlocale' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"setlocale --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "setlocale: Configure system environment locale variables.\n\n"
|
||||||
|
printf "Usage: setlocale <locale>\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf " -h, --help Display this help screen\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid options, use \"setlocale --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
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
|
||||||
|
# Usage: setc
|
||||||
setc()
|
setc()
|
||||||
{
|
{
|
||||||
# Locale definitions
|
# Locale definitions
|
||||||
export LANG=C
|
|
||||||
export LC_MESSAGES=C
|
|
||||||
export LC_ALL=C
|
export LC_ALL=C
|
||||||
|
disp I "Locale changed to standard C (POSIX)."
|
||||||
}
|
}
|
||||||
export -f setc
|
export -f setc
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Change locale to US (needed by Steam)
|
# Build dynamic locale shortcuts from SET_LOCALE
|
||||||
# ------------------------------------------------------------------------------
|
# Expected format:
|
||||||
setus ()
|
# SET_LOCALE="fr:fr_FR.UTF-8,us:en_US.UTF-8,es:es_ES.UTF-8"
|
||||||
|
# This creates functions:
|
||||||
|
# setfr, setus, setes, ...
|
||||||
|
build_locale_shortcuts()
|
||||||
{
|
{
|
||||||
# Locale definitions
|
local cfg="${SET_LOCALE:-}"
|
||||||
export LANG=en_US.UTF-8
|
local item="" alias="" loc="" fname=""
|
||||||
export LC_MESSAGES=en_US.UTF-8
|
local -a locale_items=()
|
||||||
export LC_ALL=en_US.UTF-8
|
|
||||||
|
[[ -z "$cfg" ]] && return 0
|
||||||
|
|
||||||
|
IFS=',' read -r -a locale_items <<< "$cfg"
|
||||||
|
for item in "${locale_items[@]}"; do
|
||||||
|
# Trim surrounding spaces
|
||||||
|
item="${item#"${item%%[![:space:]]*}"}"
|
||||||
|
item="${item%"${item##*[![:space:]]}"}"
|
||||||
|
|
||||||
|
[[ -z "$item" ]] && continue
|
||||||
|
|
||||||
|
if [[ "$item" != *:* ]]; then
|
||||||
|
disp W "Ignoring invalid SET_LOCALE entry: '$item' (expected alias:locale)."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
alias="${item%%:*}"
|
||||||
|
loc="${item#*:}"
|
||||||
|
|
||||||
|
# Trim alias/locale spaces
|
||||||
|
alias="${alias#"${alias%%[![:space:]]*}"}"
|
||||||
|
alias="${alias%"${alias##*[![:space:]]}"}"
|
||||||
|
loc="${loc#"${loc%%[![:space:]]*}"}"
|
||||||
|
loc="${loc%"${loc##*[![:space:]]}"}"
|
||||||
|
|
||||||
|
# Validate alias for safe function names
|
||||||
|
if [[ ! "$alias" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
|
||||||
|
disp W "Ignoring unsafe locale alias '$alias' in SET_LOCALE."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -z "$loc" ]] && {
|
||||||
|
disp W "Ignoring empty locale for alias '$alias' in SET_LOCALE."
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
export -f setus
|
|
||||||
|
fname="set${alias}"
|
||||||
|
|
||||||
|
# Optional collision warning
|
||||||
|
if declare -F "$fname" >/dev/null 2>&1; then
|
||||||
|
disp W "Overriding existing function '$fname'."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build function dynamically
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
eval "${fname}() { setlocale \"$loc\"; }"
|
||||||
|
# shellcheck disable=SC2163
|
||||||
|
export -f "$fname"
|
||||||
|
done
|
||||||
|
|
||||||
|
unset cfg item alias loc fname locale_items
|
||||||
|
}
|
||||||
|
export -f build_locale_shortcuts
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
load_conf lang
|
||||||
|
build_locale_shortcuts
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# EOF
|
||||||
|
|||||||
220
profile.d/net.sh
220
profile.d/net.sh
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -34,38 +35,97 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Determine if parameter is a valid IPv4 address
|
# Download a resource using curl, wget, or fetch.
|
||||||
|
# Usage: dwl <url> [output_file]
|
||||||
|
dwl()
|
||||||
|
{
|
||||||
|
case "$1" in
|
||||||
|
--help|-h)
|
||||||
|
echo "Usage: dwl <url> [output_file]"
|
||||||
|
echo "Downloads a resource using curl, wget, or fetch."
|
||||||
|
echo ""
|
||||||
|
echo "Arguments:"
|
||||||
|
echo " url The full URL to download (http/https/ftp)."
|
||||||
|
echo " output_file (Optional) Path to save the file. If omitted, prints to stdout."
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
"")
|
||||||
|
echo "Error: URL argument is missing." >&2
|
||||||
|
echo "Try 'get_resource --help' for usage." >&2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
http://*|https://*|ftp://*) ;;
|
||||||
|
*)
|
||||||
|
echo "Error: '$1' does not look like a valid URL. Must start with http://, https://, or ftp://" >&2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
local url="$1"
|
||||||
|
local output="$2"
|
||||||
|
|
||||||
|
if command -v curl >/dev/null 2>&1; then
|
||||||
|
[ -z "$output" ] && curl -sL "$url" || curl -sL -o "$output" "$url"
|
||||||
|
elif command -v wget >/dev/null 2>&1; then
|
||||||
|
[ -z "$output" ] && wget -qO- "$url" || wget -q -O "$output" "$url"
|
||||||
|
elif command -v fetch >/dev/null 2>&1; then
|
||||||
|
[ -z "$output" ] && fetch -o - "$url" || fetch -o "$output" "$url"
|
||||||
|
else
|
||||||
|
echo "Error: No download utility (curl, wget, or fetch) found." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
export -f dwl
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Determine if parameter is a valid IPv4 address
|
||||||
|
# Usage: isipv4 <ip_address>
|
||||||
isipv4()
|
isipv4()
|
||||||
{
|
{
|
||||||
# Set up local variables
|
# Set up local variables
|
||||||
local ip=$1
|
local ip=$1
|
||||||
|
[[ -z $ip ]] && return 1
|
||||||
|
|
||||||
# Start with a regex format test
|
# Start with a regex format test (four octets)
|
||||||
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
if [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||||
local old_ifs=$IFS
|
local old_ifs=$IFS
|
||||||
IFS="."
|
IFS='.'
|
||||||
ip=($ip)
|
read -r -a ip_arr <<< "$ip"
|
||||||
IFS=$old_ifs
|
IFS=$old_ifs
|
||||||
if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
|
|
||||||
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then
|
# Ensure each octet is between 0 and 255
|
||||||
if [[ -t 1 ]]; then
|
local oct
|
||||||
disp "The given IPv4 is valid."
|
for oct in "${ip_arr[@]}"; do
|
||||||
|
# Reject leading plus/minus or empty entries
|
||||||
|
if [[ -z $oct || $oct =~ [^0-9] ]]; then
|
||||||
|
[[ -t 1 ]] && disp "The given parameter is NOT a valid IPv4."
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
|
if (( oct > 255 )); then
|
||||||
|
[[ -t 1 ]] && disp "The given parameter is NOT a valid IPv4."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ -t 1 ]] && disp "The given IPv4 is valid."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
if [[ -t 1 ]]; then
|
[[ -t 1 ]] && disp "The given parameter is NOT a valid IPv4."
|
||||||
disp "The given parameter is NOT a valid IPv4."
|
|
||||||
fi
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
export -f isipv4
|
export -f isipv4
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Determine if parameter is a valid IPv4 address
|
# Determine if parameter is a valid IPv6 address
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: isipv6 <ip_address>
|
||||||
isipv6()
|
isipv6()
|
||||||
{
|
{
|
||||||
local ip="$1"
|
local ip="$1"
|
||||||
@@ -82,3 +142,131 @@ isipv6 ()
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
export -f isipv6
|
export -f isipv6
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Encode a string so it can be used as a URL parameter
|
||||||
|
# Usage: urlencode <string>
|
||||||
|
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 '%s' "$c" ;;
|
||||||
|
' ') printf '+' ;;
|
||||||
|
*) printf '%%%02X' "'$c" #| cut -d' ' -f2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
export -f urlencode
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Fetch and display external IP information
|
||||||
|
# Usage: myextip [-i|--ip] [-s|--isp] [-l|--loc] [-c|--coord]
|
||||||
|
# If no option is provided, all information will be displayed.
|
||||||
|
# Options:
|
||||||
|
# -h, --help Display help screen
|
||||||
|
# -i, --ip Display only the external IP address
|
||||||
|
# -s, --isp Display only the ISP name
|
||||||
|
# -l, --loc Display only the location (city, region, country)
|
||||||
|
# -c, --coord Display only the coordinates (latitude, longitude)
|
||||||
|
# -a, --as Display only the Autonomous System (AS) information
|
||||||
|
# -R, --raw Display raw JSON response
|
||||||
|
myextip() {
|
||||||
|
local show_ip=false show_isp=false show_loc=false
|
||||||
|
local show_coord=false show_as=false show_raw=false
|
||||||
|
local all=true
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ "$#" -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-i|--ip)
|
||||||
|
show_ip=true
|
||||||
|
all=false
|
||||||
|
;;
|
||||||
|
-s|--isp)
|
||||||
|
show_isp=true
|
||||||
|
all=false
|
||||||
|
;;
|
||||||
|
-l|--loc)
|
||||||
|
show_loc=true
|
||||||
|
all=false
|
||||||
|
;;
|
||||||
|
-c|--coord)
|
||||||
|
show_coord=true
|
||||||
|
all=false
|
||||||
|
;;
|
||||||
|
-a|--as)
|
||||||
|
show_as=true
|
||||||
|
all=false
|
||||||
|
;;
|
||||||
|
-R|--raw)
|
||||||
|
all=false
|
||||||
|
show_raw=true
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
printf "Fetch and display external IP information.\n\n"
|
||||||
|
printf "Usage: myextip [-i|--ip] [-s|--isp] [-l|--loc] [-c|--coord] [-a|--as] [-R|--raw]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\tDisplay this help screen\n"
|
||||||
|
printf "\t-i, --ip\tDisplay only the external IP address\n"
|
||||||
|
printf "\t-s, --isp\tDisplay only the ISP name\n"
|
||||||
|
printf "\t-l, --loc\tDisplay only the location (city, region, country)\n"
|
||||||
|
printf "\t-c, --coord\tDisplay only the coordinates (latitude, longitude)\n"
|
||||||
|
printf "\t-a, --as\tDisplay only the Autonomous System (AS) information\n"
|
||||||
|
printf "\t-R, --raw\tDisplay raw JSON response\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Unknown option: $1, use \"myextip --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# Fetch data. Allow overriding endpoint via env var MYEXTIP_URL
|
||||||
|
local MYEXTIP_URL
|
||||||
|
MYEXTIP_URL=${MYEXTIP_URL:-http://ip-api.com/json/}
|
||||||
|
|
||||||
|
local response
|
||||||
|
if ! response=$(dwl "$MYEXTIP_URL"); then
|
||||||
|
disp E "Failed to fetch external IP information from $MYEXTIP_URL"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse with jq when available and when raw wasn't requested. The jq filter
|
||||||
|
# is tolerant to field-name differences between providers (ip-api / ipinfo).
|
||||||
|
if command -v jq >/dev/null 2>&1 && [[ "$show_raw" != true ]]; then
|
||||||
|
echo "$response" | jq -r --argjson all "$all" --argjson ip "$show_ip" \
|
||||||
|
--argjson isp "$show_isp" --argjson loc "$show_loc" \
|
||||||
|
--argjson coord "$show_coord" --argjson as "$show_as" '
|
||||||
|
[
|
||||||
|
(if $all or $ip then "IP Address : \(.query // .ip)" else empty end),
|
||||||
|
(if $all or $isp then "ISP : \(.isp // .org)" else empty end),
|
||||||
|
(if $all or $loc then
|
||||||
|
("Location : " + ((.city // "") + (if .city then ", " else "" end) + (if .regionName then .regionName else .region end) + (if .country then ", " + .country else "" end)))
|
||||||
|
else empty end),
|
||||||
|
(if $all or $coord then (if (.lat and .lon) then "Coordinates: \(.lat), \(.lon)" elif .loc then "Coordinates: \(.loc)" else empty end) else empty end),
|
||||||
|
(if $all or $as then "AS : \(.as // .org)" else empty end)
|
||||||
|
] | .[]'
|
||||||
|
else
|
||||||
|
[[ "$show_raw" != true ]] && disp W "jq is not installed, displaying raw JSON response."
|
||||||
|
echo "$response"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
export -f myextip
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,46 +36,64 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Look for a package within installed one
|
# Look for a package within installed one
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: dpkgs <string>
|
||||||
dpkgs ()
|
pkgs()
|
||||||
{
|
{
|
||||||
local count=0
|
local ignore_case=0
|
||||||
for opt in $@ ; do
|
|
||||||
case $opt in
|
local PARSED
|
||||||
"-h"|"--help")
|
PARSED=$(getopt -o hi --long help,ignore-case -n 'pkgs' -- "$@")
|
||||||
echo "dpkgs: look for an installed package by it's name."
|
if [[ $? -ne 0 ]]; then
|
||||||
echo
|
disp E "Invalid options, use \"pkgs --help\" to display usage."
|
||||||
echo "Usage: dpkgs <string>"
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "pkgs: Look for an installed package by its name.\n\n"
|
||||||
|
printf "Usage: pkgs [options] <string>\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\tDisplay this help screen\n"
|
||||||
|
printf "\t-i, --ignore-case\tIgnore case distinctions\n"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
-i|--ignore-case)
|
||||||
"-"*)
|
ignore_case=1
|
||||||
disp E "Invalid option, use \"dpkgs --help\" to display usage."
|
shift
|
||||||
echo
|
;;
|
||||||
return 1
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
local pkg=$1 && shift
|
disp E "Invalid option: $1"
|
||||||
count=$(( $count + 1 ))
|
|
||||||
[[ $count -gt 1 ]] &&
|
|
||||||
disp E "Please specify a package name, without space, eventually partial." &&
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
[[ $count -lt 1 ]] &&
|
|
||||||
disp E "Please specify a package name, without space, eventually partial." &&
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if [[ $(command -v dpkg >/dev/null 2>&1) ]]; then
|
local pkg="$1"
|
||||||
dpkg -l | grep $pkg
|
[[ -z "$pkg" ]] && {
|
||||||
elif [[ $(command -v rpm >/dev/null 2>&1) ]]; then
|
disp E "Please specify a package name, without space, eventually partial."
|
||||||
rpm -qa | grep $pkg
|
return 1
|
||||||
else
|
}
|
||||||
|
|
||||||
|
# Build grep command
|
||||||
|
local grep_opt=""
|
||||||
|
(( ignore_case )) && grep_opt="-i"
|
||||||
|
|
||||||
|
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."
|
disp E "No usable package manager seems unavialable."
|
||||||
return 2
|
return 2
|
||||||
fi
|
fi
|
||||||
|
$cmd | grep $grep_opt $pkg
|
||||||
}
|
}
|
||||||
export -f dpkgs
|
export -f pkgs
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,19 +36,93 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Search processes matching the given string
|
# Search processes matching the given string
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: ppg <string>
|
||||||
ppg()
|
ppg()
|
||||||
{
|
{
|
||||||
ps -edf | grep $@ | grep -v "grep $@"
|
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||||
|
printf "ppg: Search processes matching the given string.\n\n"
|
||||||
|
printf "Usage: ppg <string>\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
disp E "Usage: ppg <string>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
ps -edf | grep "$@" | grep -v "grep $@"
|
||||||
}
|
}
|
||||||
export -f ppg
|
export -f ppg
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# List processes owned by a specific user
|
||||||
|
# Usage: ppu <username>
|
||||||
|
ppu()
|
||||||
|
{
|
||||||
|
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||||
|
printf "ppu: List processes owned by a specific user.\n\n"
|
||||||
|
printf "Usage: ppu <username>\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
disp E "Usage: ppu <username>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -u lists processes for a specific user
|
||||||
|
# -o provides a clean, standard output format
|
||||||
|
ps -u "$1" -o pid,user,%cpu,%mem,start,time,command
|
||||||
|
}
|
||||||
|
export -f ppu
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# List processes by exact command name (no path/parameters)
|
||||||
|
# Usage: ppn <command_name>
|
||||||
|
ppn()
|
||||||
|
{
|
||||||
|
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||||
|
printf "ppn: List processes by exact command name (no path/parameters).\n\n"
|
||||||
|
printf "Usage: ppn <command_name>\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
disp E "Usage: ppn <command_name>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -e: select all processes
|
||||||
|
# -o: specify custom output columns (PID and Command name)
|
||||||
|
# grep -w: ensures exact word matching so 'bash' doesn't match 'dbash'
|
||||||
|
ps -eo pid,comm | grep -w "$1"
|
||||||
|
}
|
||||||
|
export -f ppn
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Get PID list of the given process name
|
# Get PID list of the given process name
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: ppid <process_name [process_name2 ...]>
|
||||||
gpid()
|
gpid()
|
||||||
{
|
{
|
||||||
|
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||||
|
printf "gpid: Get PID list of the given process name.\n\n"
|
||||||
|
printf "Usage: gpid <process_name [process_name2 ...]>\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
disp E "Usage: gpid <process_name [process_name2 ...]>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
[[ $UID -eq 0 ]] && local psopt="-A"
|
[[ $UID -eq 0 ]] && local psopt="-A"
|
||||||
[[ $# -eq 1 ]] && local single=1
|
[[ $# -eq 1 ]] && local single=1
|
||||||
for pid in $@; do
|
for pid in $@; do
|
||||||
@@ -61,15 +136,65 @@ gpid ()
|
|||||||
[[ $result ]] || return 1
|
[[ $result ]] || return 1
|
||||||
}
|
}
|
||||||
export -f gpid
|
export -f gpid
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Kill all processes owned by the given users
|
# Kill all processes owned by the given users (kill user)
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: ku <username1 [username2 ...]>
|
||||||
ku()
|
ku()
|
||||||
{
|
{
|
||||||
|
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||||
|
printf "ku: Kill all processes owned by the given users.\n\n"
|
||||||
|
printf "Usage: ku <username1 [username2 ...]>\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
disp E "Usage: ku <username1 [username2 ...]>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
for u in $@; do
|
for u in $@; do
|
||||||
killall -u $u
|
killall -u "$u"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
export -f ku
|
export -f ku
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Kill all children of a process then the process (kill tree)
|
||||||
|
# Usage: kt <pid> [kill_options]
|
||||||
|
kt()
|
||||||
|
{
|
||||||
|
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||||
|
printf "kt: Kill all children of a process then the process (kill tree).\n\n"
|
||||||
|
printf "Usage: kt <pid> [kill_options]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
disp E "Usage: ppg <string>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local parent_pid="$1"
|
||||||
|
shift
|
||||||
|
if [[ "$parent_pid" == "0" || "$parent_pid" == "1" ]]; then
|
||||||
|
disp E "Safety abort: Refusing to kill PID $parent_pid (system critical)."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
children_pids=$(pgrep -P "$parent_pid")
|
||||||
|
|
||||||
|
for pid in $children_pids; do
|
||||||
|
kt "$pid" "$@" || break
|
||||||
|
done
|
||||||
|
kill "$@" "$parent_pid"
|
||||||
|
}
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,17 +36,26 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# timer_* functions : internal timing function for prompt
|
# timer_* functions : internal timing function for prompt
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: timer_now
|
||||||
|
# This function returns the current time in nanoseconds since the epoch. It
|
||||||
|
# first tries to use the %N format specifier for nanoseconds, but if that is
|
||||||
|
# not supported (e.g., on older systems), it falls back to seconds.
|
||||||
function timer_now
|
function timer_now
|
||||||
{
|
{
|
||||||
date +%s%N
|
date +%s%N 2>/dev/null || date +%s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Usage: timer_start
|
||||||
|
# This function initializes the timer_start variable with the current time in
|
||||||
|
# nanoseconds. It is used to measure the elapsed time for the prompt.
|
||||||
function timer_start
|
function timer_start
|
||||||
{
|
{
|
||||||
timer_start=${timer_start:-$(timer_now)}
|
timer_start=${timer_start:-$(timer_now)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Usage: timer_stop
|
||||||
|
# This function calculates the elapsed time since timer_start and formats it
|
||||||
|
# into a human-readable string with appropriate units (us, ms, s, m, h
|
||||||
function timer_stop
|
function timer_stop
|
||||||
{
|
{
|
||||||
local delta_us=$((($(timer_now) - $timer_start) / 1000))
|
local delta_us=$((($(timer_now) - $timer_start) / 1000))
|
||||||
@@ -74,23 +84,26 @@ function timer_stop
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Function triguered internaly by bash : defining prompt
|
# Function triggered internally by bash : defining prompt
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: set_prompt
|
||||||
|
# This function is called by bash before displaying the prompt. It sets the
|
||||||
|
# PS1 variable to a custom prompt that includes the exit status of the last
|
||||||
|
# command, the elapsed time of the last command, and the current user and host.
|
||||||
set_prompt()
|
set_prompt()
|
||||||
{
|
{
|
||||||
Last_Command=$? # Must come first!
|
local Last_Command=$? # Must come first!
|
||||||
Blue='\[\e[0;34m\]'
|
local Blue='\[\e[0;34m\]'
|
||||||
White='\[\e[01;37m\]'
|
local White='\[\e[01;37m\]'
|
||||||
Yellow='\[\e[01;93m\]'
|
local Yellow='\[\e[01;93m\]'
|
||||||
Red='\[\e[01;31m\]'
|
local Red='\[\e[01;31m\]'
|
||||||
Green='\[\e[01;32m\]'
|
local Green='\[\e[01;32m\]'
|
||||||
OnGrey='\[\e[47m\]'
|
local OnGrey='\[\e[47m\]'
|
||||||
OnRed='\[\e[41m\]'
|
local OnRed='\[\e[41m\]'
|
||||||
OnBlue='\[\e[44m\]'
|
local OnBlue='\[\e[44m\]'
|
||||||
ICyan='\[\e[0;96m\]'
|
local ICyan='\[\e[0;96m\]'
|
||||||
Default='\[\e[00m\]'
|
local Default='\[\e[00m\]'
|
||||||
FancyX='\342\234\227'
|
local FancyX='\342\234\227'
|
||||||
Checkmark='\342\234\223'
|
local Checkmark='\342\234\223'
|
||||||
|
|
||||||
# Begin with time
|
# Begin with time
|
||||||
PS1="\[\e[s$Blue$OnGrey [ \t ] $OnBlue"
|
PS1="\[\e[s$Blue$OnGrey [ \t ] $OnBlue"
|
||||||
@@ -123,3 +136,7 @@ set_prompt ()
|
|||||||
# the text color to the default.
|
# the text color to the default.
|
||||||
PS1+="$ICyan\\w \\\$$Default "
|
PS1+="$ICyan\\w \\\$$Default "
|
||||||
}
|
}
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
125
profile.d/pwd.sh
125
profile.d/pwd.sh
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,97 +36,109 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# genpwd : generate a password with different criteria
|
# genpwd : generate a password with different criteria
|
||||||
# default 16 car with up and low car, symbol and number
|
# Usage: genpwd [options] [--extracars=<cars>] [--length=<n>] [nb_passwd]
|
||||||
|
# Options:
|
||||||
|
# -h, --help Display that help screen
|
||||||
|
# -s, --nosymbols Exclude symbols
|
||||||
|
# -n, --nonumbers Exclude numbers
|
||||||
|
# -u, --noup Exclude uppercase letters
|
||||||
|
# -l, --nolow Exclude lowercase letters
|
||||||
|
# -e=<c>, --extracars=<c>
|
||||||
|
# Add the given caracters to the possible caracter list
|
||||||
|
# -L=<n>, --length=<n>
|
||||||
|
# Set length of the password (default is 16)
|
||||||
|
# -o=<n>, --occurences=<n>
|
||||||
|
# Set the maximum occurences of a same caracter (default is 2)
|
||||||
# The function is very slow on Windows
|
# The function is very slow on Windows
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
genpwd()
|
genpwd()
|
||||||
{
|
{
|
||||||
local length=16
|
local length=16
|
||||||
local occurs=2 # Bug, if set to 1, seems to be ignored
|
local occurs=2 # Bug, if set to 1, seems to be ignored
|
||||||
local symb=1 maj=1 min=1 numb=1
|
local symb=1 maj=1 min=1 numb=1
|
||||||
local nbpwd=1
|
local nbpwd=1
|
||||||
|
local extcar
|
||||||
|
|
||||||
for opt in $@; do
|
local PARSED
|
||||||
case $opt in
|
PARSED=$(getopt -o hsnu l e:L:o: --long \
|
||||||
"-h"|"--help")
|
help,nosymbols,nonumbers,noup,nolow,extracars:,length:,occurences: -n 'genpwd' -- "$@")
|
||||||
echo "genpwd: generate one or more secure random password."
|
if [[ $? -ne 0 ]]; then return 1; fi
|
||||||
echo
|
eval set -- "$PARSED"
|
||||||
echo "Usage: genpwd [options] [--extracars=<cars>] [--length=<n>] [nb_passwd]"
|
|
||||||
echo
|
while true; do
|
||||||
echo "Options:"
|
case "$1" in
|
||||||
echo " -h, --help Display that help screen"
|
-h|--help)
|
||||||
echo " -s, --nosymbols Exclude symbols"
|
printf "genpwd: Generate secure random password(s).\n\n"
|
||||||
echo " -n, --nonumbers Exclude numbers"
|
printf "Usage: genpwd [options] [nb_passwd]\n\n"
|
||||||
echo " -u, --noup Exclude uppercase letters"
|
printf "Options:\n"
|
||||||
echo " -l, --nolow Exclude lowercase letters"
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
echo " -e=<c>, --extracars=<c>"
|
printf "\t-s, --nosymbols\t\tExclude symbols\n"
|
||||||
echo " Add the given caracters to the possible caracter list"
|
printf "\t-n, --nonumbers\t\tExclude numbers\n"
|
||||||
echo " -L=<n>, --length=<n>"
|
printf "\t-u, --noup\t\tExclude uppercase letters\n"
|
||||||
echo " Set length of the password (default is $length)"
|
printf "\t-l, --nolow\t\tExclude lowercase letters\n"
|
||||||
echo " -o=<n>, --occurences=<n>"
|
printf "\t-e, --extracars <c>\tAdd characters to list\n"
|
||||||
echo " Set the maximum occurences of a same caracter (default is $occurs)"
|
printf "\t-L, --length <n>\tSet password length (default: 16)\n"
|
||||||
echo
|
printf "\t-o, --occurences <n>\tMax occurences per character (default: 2)\n"
|
||||||
echo "If the --extracars parameter is given, at least one of the given caracter will"
|
|
||||||
echo "be used in the final password."
|
|
||||||
echo
|
|
||||||
echo "Please note that some caracters might be interpreted by Bash or Awk programs,"
|
|
||||||
echo "and thus, cannot be used without provoquing errors. Those identified caracters"
|
|
||||||
echo "are :"
|
|
||||||
echo ' * ? \ $ { }'
|
|
||||||
echo
|
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
"-s"|"--nosymbols")
|
-s|--nosymbols)
|
||||||
symb=0
|
symb=0
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
"-n"|"--nonumbers")
|
-n|--nonumbers)
|
||||||
numb=0
|
numb=0
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
"-u"|"--noup")
|
-u|--noup)
|
||||||
maj=0
|
maj=0
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
"-l"|"--nolow")
|
-l|--nolow)
|
||||||
min=0
|
min=0
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
"-e"?*|"--extracars"?*)
|
-e|--extracars)
|
||||||
local extcar=$(echo "$opt" | cut -f 2- -d '=')
|
extcar="$2"
|
||||||
|
shift 2
|
||||||
;;
|
;;
|
||||||
"-L"?*|"--length"?*)
|
-L|--length)
|
||||||
local length=$(echo "$opt" | cut -f 2- -d '=')
|
length="$2"
|
||||||
if ! [[ $length =~ ^[0-9]+$ ]]; then
|
if ! [[ $length =~ ^[0-9]+$ ]]; then
|
||||||
disp E "The --length parameter requires a number."
|
disp E "The --length parameter requires a number."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
shift 2
|
||||||
;;
|
;;
|
||||||
"-o"?*|"--occurences"?*)
|
-o|--occurences)
|
||||||
local occurs=$(echo "$opt" | cut -f 2- -d '=')
|
occurs="$2"
|
||||||
if ! [[ $occurs =~ ^[1-9]+$ ]]; then
|
if ! [[ $occurs =~ ^[1-9]+$ ]]; then
|
||||||
disp E "The --occurs parameter requires a number from 1 to 9."
|
disp E "The --occurs parameter requires a number from 1 to 9."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
shift 2
|
||||||
;;
|
;;
|
||||||
"-*")
|
--)
|
||||||
disp E "Unknow parameter ${opt}."
|
shift; break
|
||||||
return 1
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
if ! [[ $opt =~ ^[1-9]+$ ]]; then
|
break
|
||||||
disp E "Unknow parameter ${opt}."
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
local nbpwd=$opt
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [[ -n "$1" ]]; then
|
||||||
|
nbpwd="$1"
|
||||||
|
if ! [[ $nbpwd =~ ^[0-9]+$ ]]; then
|
||||||
|
disp E "The number of password to generate must be a number."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Function selecting a random caracter from the list in parameter
|
# 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
|
# 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
|
# elsewhere, we choose an other char, to compensate weak bash randomizer
|
||||||
while [[ -z $char ]]; do
|
while [[ -z $char ]]; do
|
||||||
local char=$(echo ${1:RANDOM%${#1}:1} $RANDOM)
|
local char="${1:RANDOM%${#1}:1} $RANDOM"
|
||||||
if [[ $(awk -F"$char" '{print NF-1}' <<<"$picked") -gt $occurs ]]; then
|
if [[ $(awk -F"$char" '{print NF-1}' <<<"$picked") -gt $occurs ]]; then
|
||||||
unset char
|
unset char
|
||||||
fi
|
fi
|
||||||
@@ -135,7 +148,7 @@ genpwd()
|
|||||||
}
|
}
|
||||||
|
|
||||||
disp I "Generating $nbpwd passwords, please wait..."
|
disp I "Generating $nbpwd passwords, please wait..."
|
||||||
for n in $( seq 1 $nbpwd ); do
|
for (( n=1; n<=nbpwd; n++ )); do
|
||||||
{
|
{
|
||||||
local carset='' # store final caracter set to use
|
local carset='' # store final caracter set to use
|
||||||
local picked='' # store already used caracter
|
local picked='' # store already used caracter
|
||||||
@@ -184,3 +197,7 @@ genpwd()
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
export -f genpwd
|
export -f genpwd
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -34,93 +35,213 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Let the rain fall
|
# Generic rain-like engine and presets
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
rain()
|
_rain_build_colors()
|
||||||
{
|
{
|
||||||
local exit_st=0
|
local base_color="$1"
|
||||||
local rain_cars=("|" "│" "┃" "┆" "┇" "┊" "┋" "╽" "╿")
|
RAIN_ENGINE_COLORS=()
|
||||||
local rain_colors=("\e[37m" "\e[37;1m")
|
|
||||||
# More from 256 color mode
|
case $base_color in
|
||||||
for i in {244..255}; do
|
green)
|
||||||
rain_colors=( "${rain_colors[@]}" "\e[38;5;${i}m" )
|
for i in {22..28} {34..40} {46..48}; do RAIN_ENGINE_COLORS+=("\e[38;5;${i}m"); done ;;
|
||||||
done
|
blue)
|
||||||
local rain_tab=${#rain_cars[@]}
|
for i in {17..21} {27..33} {39..45}; do RAIN_ENGINE_COLORS+=("\e[38;5;${i}m"); done ;;
|
||||||
|
red)
|
||||||
|
for i in {52..52} {88..88} {124..124} {160..160} {196..201}; do RAIN_ENGINE_COLORS+=("\e[38;5;${i}m"); done ;;
|
||||||
|
yellow)
|
||||||
|
for i in {58..58} {100..100} {142..142} {184..184} {226..229}; do RAIN_ENGINE_COLORS+=("\e[38;5;${i}m"); done ;;
|
||||||
|
cyan)
|
||||||
|
for i in {30..31} {37..38} {44..45} {50..51}; do RAIN_ENGINE_COLORS+=("\e[38;5;${i}m"); done ;;
|
||||||
|
*)
|
||||||
|
RAIN_ENGINE_COLORS=("\e[37m" "\e[37;1m")
|
||||||
|
for i in {244..255}; do RAIN_ENGINE_COLORS+=("\e[38;5;${i}m"); done ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
_rain_build_chars()
|
||||||
|
{
|
||||||
|
local mode="$1"
|
||||||
|
local charset="$2"
|
||||||
|
RAIN_ENGINE_CHARS=()
|
||||||
|
|
||||||
|
case "$mode" in
|
||||||
|
matrix)
|
||||||
|
case "$charset" in
|
||||||
|
""|binary)
|
||||||
|
RAIN_ENGINE_CHARS=("0" "1")
|
||||||
|
;;
|
||||||
|
kana|kanji)
|
||||||
|
# Half-width katakana set, generally rendered as single-cell glyphs.
|
||||||
|
RAIN_ENGINE_CHARS=("ア" "イ" "ウ" "エ" "オ" "カ" "キ" "ク" "ケ" "コ" "サ" "シ" "ス" "セ" "ソ" "タ" "チ" "ツ" "テ" "ト" "ナ" "ニ" "ヌ" "ネ" "ノ" "ハ" "ヒ" "フ" "ヘ" "ホ" "マ" "ミ" "ム" "メ" "モ" "ヤ" "ユ" "ヨ" "ラ" "リ" "ル" "レ" "ロ" "ワ" "ン")
|
||||||
|
;;
|
||||||
|
ascii)
|
||||||
|
RAIN_ENGINE_CHARS=("0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Unknown charset: ${charset} (supported: binary, kana, ascii)."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
RAIN_ENGINE_CHARS=("|" "│" "┃" "┆" "┇" "┊" "┋" "╽" "╿")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_rain_normalize_speed()
|
||||||
|
{
|
||||||
|
local raw_speed="$1"
|
||||||
|
|
||||||
|
# Accept integer/floating values. UI scale is centiseconds by default:
|
||||||
|
# 5 -> 0.05s, 2.5 -> 0.025s. Values < 1 are treated as direct seconds
|
||||||
|
# for backward compatibility (e.g. 0.03).
|
||||||
|
if [[ ! "$raw_speed" =~ ^[0-9]+([.][0-9]+)?$ ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if awk -v s="$raw_speed" 'BEGIN { exit !(s < 1) }'; then
|
||||||
|
printf "%s" "$raw_speed"
|
||||||
|
else
|
||||||
|
awk -v s="$raw_speed" 'BEGIN { printf "%.3f", s / 100 }'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_rain_engine()
|
||||||
|
{
|
||||||
|
local step_duration="$1"
|
||||||
|
local base_color="$2"
|
||||||
|
local mode="$3"
|
||||||
|
local charset="$4"
|
||||||
|
|
||||||
|
command -v tput >/dev/null 2>&1 || {
|
||||||
|
disp E "The program 'tput' is required but not installed."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_rain_build_colors "$base_color"
|
||||||
|
_rain_build_chars "$mode" "$charset" || return 1
|
||||||
|
|
||||||
|
local rain_colors=("${RAIN_ENGINE_COLORS[@]}")
|
||||||
|
local rain_chars=("${RAIN_ENGINE_CHARS[@]}")
|
||||||
local rain_color_tab=${#rain_colors[@]}
|
local rain_color_tab=${#rain_colors[@]}
|
||||||
|
local rain_tab=${#rain_chars[@]}
|
||||||
|
local matrix_head_color=$'\e[1;97m'
|
||||||
|
|
||||||
|
local exit_st=0
|
||||||
local num_rain_metadata=5
|
local num_rain_metadata=5
|
||||||
local term_height=$(tput lines)
|
local term_height=0 term_width=0
|
||||||
local term_width=$(tput cols)
|
|
||||||
local step_duration=0.050
|
|
||||||
local X=0 Y=0 drop_length=0 rain_drop=0
|
local X=0 Y=0 drop_length=0 rain_drop=0
|
||||||
local max_rain_width=0 new_rain_odd=0 falling_odd=0
|
local max_rain_width=0 max_rain_height=0
|
||||||
|
local new_rain_odd=0 falling_odd=0
|
||||||
|
local term_area=0
|
||||||
|
local frame_sleep="$step_duration"
|
||||||
|
|
||||||
|
sigwinch()
|
||||||
sigwinch() {
|
{
|
||||||
term_width=$(tput cols)
|
term_width=$(tput cols)
|
||||||
term_height=$(tput lines)
|
term_height=$(tput lines)
|
||||||
#step_duration=0.025
|
((term_area = term_width * term_height))
|
||||||
(( max_rain_width = term_width * term_height / 4 ))
|
|
||||||
|
case "$mode" in
|
||||||
|
matrix)
|
||||||
|
((max_rain_width = term_area / 3))
|
||||||
|
((max_rain_height = term_height < 8 ? 1 : term_height / 6))
|
||||||
|
((new_rain_odd = term_height > 50 ? 100 : term_height * 2))
|
||||||
|
((new_rain_odd = new_rain_odd * 85 / 100))
|
||||||
|
((falling_odd = 100))
|
||||||
|
|
||||||
|
# Adapt cadence and density to terminal size for smoother rendering.
|
||||||
|
if ((term_area < 1200)); then
|
||||||
|
((max_rain_width = term_area / 4))
|
||||||
|
frame_sleep=$(awk -v s="$step_duration" 'BEGIN { printf "%.3f", s * 1.15 }')
|
||||||
|
elif ((term_area > 5000)); then
|
||||||
|
((max_rain_width = term_area / 2))
|
||||||
|
frame_sleep=$(awk -v s="$step_duration" 'BEGIN { printf "%.3f", s * 0.85 }')
|
||||||
|
else
|
||||||
|
frame_sleep="$step_duration"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
((max_rain_width = term_area / 4))
|
||||||
((max_rain_height = term_height < 10 ? 1 : term_height / 10))
|
((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 = term_height > 50 ? 100 : term_height * 2))
|
||||||
((new_rain_odd = new_rain_odd * 75 / 100))
|
((new_rain_odd = new_rain_odd * 75 / 100))
|
||||||
((falling_odd = term_height > 25 ? 100 : term_height * 4))
|
((falling_odd = term_height > 25 ? 100 : term_height * 4))
|
||||||
((falling_odd = falling_odd * 90 / 100))
|
((falling_odd = falling_odd * 90 / 100))
|
||||||
|
frame_sleep="$step_duration"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
do_exit() {
|
do_exit()
|
||||||
|
{
|
||||||
exit_st=1
|
exit_st=1
|
||||||
}
|
}
|
||||||
|
|
||||||
do_render() {
|
do_render()
|
||||||
# Clean screen first
|
{
|
||||||
local idx=0
|
local idx=0 y=0 drop_color="" current_char="" render_color=""
|
||||||
|
|
||||||
for ((idx = 0; idx < num_rains * num_rain_metadata; idx += num_rain_metadata)); do
|
for ((idx = 0; idx < num_rains * num_rain_metadata; idx += num_rain_metadata)); do
|
||||||
X=${rains[idx]}
|
X=${rains[idx]}
|
||||||
Y=${rains[idx + 1]}
|
Y=${rains[idx + 1]}
|
||||||
drop_length=${rains[idx + 4]}
|
drop_length=${rains[idx + 4]}
|
||||||
for ((y = Y; y < Y + drop_length; y++)); do
|
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 "
|
printf "\e[%d;%dH " "$y" "$X"
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
for ((idx = 0; idx < num_rains * num_rain_metadata; idx += num_rain_metadata)); do
|
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}")
|
||||||
rains=("${rains[@]:0:idx}"
|
|
||||||
"${rains[@]:idx+num_rain_metadata:num_rains*num_rain_metadata}")
|
|
||||||
((num_rains--))
|
((num_rains--))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
X=${rains[idx]}
|
X=${rains[idx]}
|
||||||
Y=${rains[idx + 1]}
|
Y=${rains[idx + 1]}
|
||||||
rain_drop=${rains[idx + 2]}
|
rain_drop=${rains[idx + 2]}
|
||||||
drop_color=${rains[idx + 3]}
|
drop_color=${rains[idx + 3]}
|
||||||
drop_length=${rains[idx + 4]}
|
drop_length=${rains[idx + 4]}
|
||||||
|
|
||||||
for ((y = Y; y < Y + drop_length; y++)); do
|
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}"
|
if [[ "$mode" == "matrix" ]]; then
|
||||||
|
current_char="${rain_chars[rain_tab * RANDOM / 32768]}"
|
||||||
|
if ((y == Y + drop_length - 1)); then
|
||||||
|
render_color="$matrix_head_color"
|
||||||
|
else
|
||||||
|
render_color="$drop_color"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
current_char="$rain_drop"
|
||||||
|
render_color="$drop_color"
|
||||||
|
fi
|
||||||
|
printf "\e[%d;%dH%b%s" "$y" "$X" "$render_color" "$current_char"
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
trap do_exit TERM INT
|
trap do_exit TERM INT
|
||||||
trap sigwinch WINCH
|
trap sigwinch WINCH
|
||||||
# No echo stdin and hide the cursor
|
|
||||||
stty -echo
|
stty -echo
|
||||||
echo -ne "\e[?25l"
|
printf "\e[?25l"
|
||||||
|
printf "\e[2J"
|
||||||
|
|
||||||
echo -ne "\e[2J"
|
|
||||||
local rains=()
|
local rains=()
|
||||||
local num_rains=0
|
local num_rains=0
|
||||||
|
local ch=""
|
||||||
|
|
||||||
sigwinch
|
sigwinch
|
||||||
while ((exit_st <= 0)); do
|
while ((exit_st <= 0)); do
|
||||||
if (( $exit_st <=0 )); then
|
read -r -n 1 -t "$frame_sleep" ch
|
||||||
read -n 1 -t $step_duration ch
|
|
||||||
case "$ch" in
|
case "$ch" in
|
||||||
q|Q)
|
q|Q)
|
||||||
do_exit
|
do_exit
|
||||||
@@ -128,8 +249,7 @@ rain()
|
|||||||
esac
|
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_chars[rain_tab * RANDOM / 32768]}"
|
||||||
rain_drop="${rain_cars[rain_tab * RANDOM / 32768]}"
|
|
||||||
drop_color="${rain_colors[rain_color_tab * RANDOM / 32768]}"
|
drop_color="${rain_colors[rain_color_tab * RANDOM / 32768]}"
|
||||||
drop_length=$((max_rain_height * RANDOM / 32768 + 1))
|
drop_length=$((max_rain_height * RANDOM / 32768 + 1))
|
||||||
X=$((term_width * RANDOM / 32768 + 1))
|
X=$((term_width * RANDOM / 32768 + 1))
|
||||||
@@ -138,17 +258,176 @@ rain()
|
|||||||
((num_rains++))
|
((num_rains++))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Let rain fall!
|
|
||||||
do_render
|
do_render
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
echo -ne "\e[${term_height};1H\e[0K"
|
|
||||||
|
|
||||||
# Show cursor and echo stdin
|
printf "\e[%d;1H\e[0K" "$term_height"
|
||||||
echo -ne "\e[?25h"
|
printf "\e[?25h"
|
||||||
stty echo
|
stty echo
|
||||||
unset exit_st
|
|
||||||
trap - TERM INT
|
trap - TERM INT
|
||||||
trap - WINCH
|
trap - WINCH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Let the rain fall (current style)
|
||||||
|
# Usage: rain [OPTIONS]
|
||||||
|
rain()
|
||||||
|
{
|
||||||
|
_rain_show_usage()
|
||||||
|
{
|
||||||
|
printf "Usage: rain [OPTIONS]\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-s, --speed NUM Set speed value (default: 5 => 0.050s).\n"
|
||||||
|
printf "\t Values >=1 use a /100 scale (5 => 0.05s).\n"
|
||||||
|
printf "\t Values <1 are interpreted as raw seconds.\n"
|
||||||
|
printf "\t-c, --color COLOR Set the color theme (default: white).\n"
|
||||||
|
printf "\t-h, --help Display this help message and exit.\n\n"
|
||||||
|
printf "Available Colors:\n"
|
||||||
|
printf "\t\e[32mgreen\e[0m\t: Matrix-like green shades\n"
|
||||||
|
printf "\t\e[34mblue\e[0m\t: Deep ocean blue gradients\n"
|
||||||
|
printf "\t\e[31mred\e[0m\t: Crimson/Blood rain\n"
|
||||||
|
printf "\t\e[33myellow\e[0m\t: Amber and gold tones\n"
|
||||||
|
printf "\t\e[36mcyan\e[0m\t: Electric cyan/turquoise\n"
|
||||||
|
printf "\twhite\t: Greyscale and white (original style)\n\n"
|
||||||
|
printf "Example: rain --color green --speed 3\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
local step_duration=0.050
|
||||||
|
local base_color="white"
|
||||||
|
|
||||||
|
while [[ "$#" -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-s|--speed)
|
||||||
|
if [[ -n "$2" && ! "$2" =~ ^- ]]; then
|
||||||
|
step_duration=$(_rain_normalize_speed "$2") || {
|
||||||
|
disp E "--speed requires a numeric value."
|
||||||
|
_rain_show_usage
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
disp E "--speed requires a numeric value."
|
||||||
|
_rain_show_usage
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-c|--color)
|
||||||
|
if [[ -n "$2" && ! "$2" =~ ^- ]]; then
|
||||||
|
base_color="$2"
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
disp E "--color requires a color name."
|
||||||
|
_rain_show_usage
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
_rain_show_usage
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Unknown option: $1"
|
||||||
|
_rain_show_usage
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
_rain_engine "$step_duration" "$base_color" "rain" ""
|
||||||
|
}
|
||||||
export -f rain
|
export -f rain
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Matrix style digital rain
|
||||||
|
# Usage: matrix [OPTIONS]
|
||||||
|
matrix()
|
||||||
|
{
|
||||||
|
_matrix_show_usage()
|
||||||
|
{
|
||||||
|
printf "Usage: matrix [OPTIONS]\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-s, --speed NUM Set speed value (default: 3.5 => 0.035s).\n"
|
||||||
|
printf "\t Values >=1 use a /100 scale (3.5 => 0.035s).\n"
|
||||||
|
printf "\t Values <1 are interpreted as raw seconds.\n"
|
||||||
|
printf "\t-c, --color COLOR Set color theme (default: green).\n"
|
||||||
|
printf "\t-C, --charset SET Character set: binary, kana, ascii (default: binary).\n"
|
||||||
|
printf "\t-h, --help Display this help message and exit.\n\n"
|
||||||
|
printf "Example: matrix -C kana -c green --speed 2\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
local step_duration=0.035
|
||||||
|
local base_color="green"
|
||||||
|
local charset="binary"
|
||||||
|
|
||||||
|
while [[ "$#" -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-s|--speed)
|
||||||
|
if [[ -n "$2" && ! "$2" =~ ^- ]]; then
|
||||||
|
step_duration=$(_rain_normalize_speed "$2") || {
|
||||||
|
disp E "--speed requires a numeric value."
|
||||||
|
_matrix_show_usage
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
disp E "--speed requires a numeric value."
|
||||||
|
_matrix_show_usage
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-c|--color)
|
||||||
|
if [[ -n "$2" && ! "$2" =~ ^- ]]; then
|
||||||
|
case "${2,,}" in
|
||||||
|
binary|kana|kanji|ascii)
|
||||||
|
disp W "'${2}' looks like a charset value. Use -C/--charset for clarity."
|
||||||
|
charset="${2,,}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
base_color="$2"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
disp E "--color requires a color name."
|
||||||
|
_matrix_show_usage
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-C|--charset)
|
||||||
|
if [[ -n "$2" && ! "$2" =~ ^- ]]; then
|
||||||
|
charset="${2,,}"
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
disp E "--charset requires a value."
|
||||||
|
_matrix_show_usage
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
_matrix_show_usage
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Unknown option: $1"
|
||||||
|
_matrix_show_usage
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
_rain_engine "$step_duration" "$base_color" "matrix" "$charset"
|
||||||
|
}
|
||||||
|
export -f matrix
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# EOF
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,20 +36,45 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Remove host from know_host (name and IP) for the active user
|
# Remove host from know_host (name and IP) for the active user
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: rmhost <hostname|ip> [hostname2|ip2 [...]]
|
||||||
rmhost()
|
rmhost()
|
||||||
{
|
{
|
||||||
if [[ "$#" -lt 1 ]]; then
|
local PARSED
|
||||||
disp E "Incorrect number of parameters."
|
PARSED=$(getopt -o h --long help -n 'rmhost' -- "$@")
|
||||||
disp E "Usage: rmhost <hostname|ip> [hostname2|ip2 [...]]"
|
if [[ $? -ne 0 ]]; then return 1; fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "rmhost: Remove host/IP from ~/.ssh/known_hosts.\n\n"
|
||||||
|
printf "Usage: rmhost <hostname|ip> [hostname2|ip2 ...]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf " -h, --help Display this help screen\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid options, use \"rmhost --help\" to display usage."
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Validation: Ensure at least one argument remains
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
disp E "Missing argument. Use 'rmhost --help' for usage."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while [[ $1 ]]; do
|
for target in "$@"; do
|
||||||
local hst=$1 && shift
|
local hst=$target
|
||||||
isipv4 $hst > /dev/null
|
isipv4 "$hst" >/dev/null
|
||||||
local v4=$?
|
local v4=$?
|
||||||
isipv6 $hst > /dev/null
|
isipv6 "$hst" >/dev/null
|
||||||
local v6=$?
|
local v6=$?
|
||||||
|
|
||||||
if [[ $v4 -eq 0 || $v6 -eq 0 ]]; then
|
if [[ $v4 -eq 0 || $v6 -eq 0 ]]; then
|
||||||
@@ -58,11 +84,15 @@ rmhost ()
|
|||||||
unset v4 v6
|
unset v4 v6
|
||||||
|
|
||||||
if [[ ! $ip && $hst ]]; then
|
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." &&
|
disp E "Impossible to extract IP from hostname." &&
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
[[ -z $ip ]] && {
|
||||||
|
disp E "Impossible to extract IP from hostname."
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $hst ]]; then
|
if [[ $hst ]]; then
|
||||||
disp I "Removing host $hst from ssh known_host..."
|
disp I "Removing host $hst from ssh known_host..."
|
||||||
@@ -76,30 +106,54 @@ rmhost ()
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
export -f rmhost
|
export -f rmhost
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Login root via SSH on the given machine
|
# Login root via SSH on the given machine
|
||||||
# ------------------------------------------------------------------------------
|
# Usage: ssr <server [ssh options]>
|
||||||
ssr()
|
ssr()
|
||||||
{
|
{
|
||||||
for opt in $@ ; do
|
local PARSED
|
||||||
case $opt in
|
PARSED=$(getopt -o h --long help -n 'ssr' -- "$@")
|
||||||
"-h"|"--help")
|
if [[ $? -ne 0 ]]; then return 1; fi
|
||||||
echo "ssr: do a root user ssh login."
|
eval set -- "$PARSED"
|
||||||
echo
|
|
||||||
echo "Usage: ssr <server [ssh options]>"
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "ssr: SSH into a server as root.\n\n"
|
||||||
|
printf "Usage: ssr <server> [ssh_options...]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid options, use \"ssr --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ ! $1 ]] &&
|
command -v ssh >/dev/null 2>&1 || {
|
||||||
disp E "Please specify the server you want to log in." &&
|
disp E "ssh is not installed."
|
||||||
|
return 127
|
||||||
|
}
|
||||||
|
[[ ! $1 ]] && {
|
||||||
|
disp E "Please specify the server you want to log in."
|
||||||
return 1
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
local srv=$1 && shift
|
local srv=$1 && shift
|
||||||
|
|
||||||
ssh -Y root@$srv $@
|
ssh -Y root@"$srv" "$@"
|
||||||
}
|
}
|
||||||
export -f ssr
|
export -f ssr
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
192
profile.d/updates.sh
Normal file
192
profile.d/updates.sh
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright (c) 2013-2026 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
|
||||||
|
# Usage: check_updates [-q]
|
||||||
|
# If -q is specified, the function will operate in quiet mode (internal use only)
|
||||||
|
check_updates()
|
||||||
|
{
|
||||||
|
local quiet=0
|
||||||
|
local PARSED=$(getopt -o hq --long help,quiet -n 'check_updates' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
disp E "Invalid options, use \"check_updates --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "check_updates: Check for new versions.\n\n"
|
||||||
|
printf "Usage: check_updates\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-q|--quiet)
|
||||||
|
quiet=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
(( $quiet != 1 )) && 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 != 1 )) && disp I "You should upgrade to last version when possible."
|
||||||
|
result=1
|
||||||
|
else
|
||||||
|
(( $quiet != 1 )) && 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
|
||||||
|
}
|
||||||
|
export -f check_updates
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Apply update to profile
|
||||||
|
# Usage: profile_upgrade
|
||||||
|
profile_upgrade()
|
||||||
|
{
|
||||||
|
local PARSED=$(getopt -o h --long help -n 'profile_upgrade' -- "$@")
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
printf "Invalid options, use \"profile_upgrade --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
eval set -- "$PARSED"
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
printf "profile_upgrade: Upgrade the profile to the latest version.\n\n"
|
||||||
|
printf "Usage: profile_upgrade\n"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
disp E "Invalid options, use \"profile_upgrade --help\" to display usage."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if check_updates -q; then
|
||||||
|
disp "No update available."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
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."
|
||||||
|
pushd "$MYPATH" || {
|
||||||
|
disp E "Failed to change directory to $MYPATH."
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
git pull || {
|
||||||
|
disp E "Git pull failed, upgrade not applyed."
|
||||||
|
popd
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
disp I "Successfully upgraded using git."
|
||||||
|
popd
|
||||||
|
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
|
||||||
|
}
|
||||||
|
export -f profile_upgrade
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# EOF
|
||||||
211
profile.sh
211
profile.sh
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
# Begin profile
|
# Begin profile
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
# Protected by the BSD3 license. Please read bellow for details.
|
# Protected by the BSD3 license. Please read bellow for details.
|
||||||
#
|
#
|
||||||
# * Redistribution and use in source and binary forms,
|
# * Redistribution and use in source and binary forms,
|
||||||
@@ -35,22 +35,24 @@
|
|||||||
# * OF SUCH DAMAGE.
|
# * OF SUCH DAMAGE.
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
export PROFVERSION="3.2.2"
|
if [[ ! $SHELL =~ bash ]]; then
|
||||||
|
echo "That environment script is designed to be used with bash being the shell."
|
||||||
export DEFAULT_CITY="Toulouse"
|
echo "Please consider using bash to enjoy our features!"
|
||||||
|
|
||||||
if [[ ! $(echo $SHELL | grep bash) ]]; then
|
|
||||||
echo "That environmet 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
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Required for associative arrays (4.0+) and namerefs (4.3+)
|
||||||
|
if ((BASH_VERSINFO[0] < 4)) || [[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 3 ]]; then
|
||||||
|
echo "[ Error ] This profile requires Bash 4.3 or higher."
|
||||||
|
echo "Current version: $BASH_VERSION"
|
||||||
|
return 1 2>/dev/null || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# path* : private functions for PATH variable management
|
# path* : private functions for PATH variable management
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
pathremove()
|
pathremove()
|
||||||
{
|
{
|
||||||
local ifs=':'
|
local IFS=':'
|
||||||
local newpath
|
local newpath
|
||||||
local dir
|
local dir
|
||||||
local pathvar=${2:-PATH}
|
local pathvar=${2:-PATH}
|
||||||
@@ -75,6 +77,109 @@ pathappend ()
|
|||||||
local pathvar=${2:-PATH}
|
local pathvar=${2:-PATH}
|
||||||
export $pathvar="${!pathvar:+${!pathvar}:}$1"
|
export $pathvar="${!pathvar:+${!pathvar}:}$1"
|
||||||
}
|
}
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Configuration file parser
|
||||||
|
parse_conf()
|
||||||
|
{
|
||||||
|
local config_file="$1"
|
||||||
|
local current_section=""
|
||||||
|
local line key value
|
||||||
|
|
||||||
|
[[ ! -f "$config_file" ]] && return 1
|
||||||
|
|
||||||
|
while IFS='=' read -r key value || [[ -n "$key" ]]; do
|
||||||
|
# Internal trimming (removes leading/trailing whitespace & CR)
|
||||||
|
key="${key%"${key##*[![:space:]]}"}"
|
||||||
|
key="${key#"${key%%[![:space:]]*}"}"
|
||||||
|
key="${key%$'\r'}" # Strip potential Windows line endings
|
||||||
|
|
||||||
|
# Skip comments and empty lines
|
||||||
|
[[ -z "$key" || "$key" =~ ^[#\;] ]] && continue
|
||||||
|
|
||||||
|
# Section Detection: [section_name]
|
||||||
|
if [[ "$key" =~ ^\[([a-zA-Z0-9_]+)\]$ ]]; then
|
||||||
|
current_section="${BASH_REMATCH[1]}"
|
||||||
|
declare -g -A "CONF_$current_section"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Secure Assignment (if inside a section)
|
||||||
|
if [[ -n "$current_section" ]]; then
|
||||||
|
# Clean the value
|
||||||
|
value="${value%"${value##*[![:space:]]}"}"
|
||||||
|
value="${value#"${value%%[![:space:]]*}"}"
|
||||||
|
value="${value%$'\r'}"
|
||||||
|
|
||||||
|
# Protect against command injection by disallowing certain characters in keys
|
||||||
|
value="${value//\`/}"
|
||||||
|
value="${value//\$\(/}"
|
||||||
|
|
||||||
|
# Correctly interpretet internal variables (e.g. $HOME)
|
||||||
|
if [[ "$value" == *\$* ]]; then
|
||||||
|
value=$(envsubst <<< "$value")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Strip quotes (handling both " and ')
|
||||||
|
value="${value%\"}"; value="${value#\"}"
|
||||||
|
value="${value%\'}"; value="${value#\'}"
|
||||||
|
|
||||||
|
# Use a nameref for safe, eval-free assignment
|
||||||
|
local -n current_array="CONF_$current_section"
|
||||||
|
current_array["$key"]="$value"
|
||||||
|
fi
|
||||||
|
done < "$config_file"
|
||||||
|
}
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Load command aliases from configuration
|
||||||
|
load_alias()
|
||||||
|
{
|
||||||
|
local section_name="CONF_$1"
|
||||||
|
|
||||||
|
# Check if the associative array exists using declare -p
|
||||||
|
[[ "$(declare -p "$section_name" 2>/dev/null)" != "declare -A"* ]] && return 1
|
||||||
|
|
||||||
|
# Create a nameref to the section array
|
||||||
|
local -n current_aliases="$section_name"
|
||||||
|
|
||||||
|
# Iterate safely over the keys of the associative array
|
||||||
|
for key in "${!current_aliases[@]}"; do
|
||||||
|
local cmd="${current_aliases[$key]}"
|
||||||
|
|
||||||
|
# Extract the base command (first word) safely without awk
|
||||||
|
local base_cmd="${cmd%% *}"
|
||||||
|
|
||||||
|
# Only alias if the base command is executable
|
||||||
|
if command -v "$base_cmd" >/dev/null 2>&1; then
|
||||||
|
alias "$key"="$cmd"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Load configuration values as environment variables
|
||||||
|
load_conf()
|
||||||
|
{
|
||||||
|
local section_name="CONF_$1"
|
||||||
|
|
||||||
|
[[ "$(declare -p "$section_name" 2>/dev/null)" != "declare -A"* ]] && return 1
|
||||||
|
|
||||||
|
local -n current_vars="$section_name"
|
||||||
|
|
||||||
|
for key in "${!current_vars[@]}"; do
|
||||||
|
# Export the key/value pair as a standard shell variable
|
||||||
|
# We use 'export' directly; Bash handles the assignment safely here
|
||||||
|
export "$key"="${current_vars[$key]}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -83,40 +188,43 @@ pathappend ()
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Store script's path (realpath -s resolve symlinks if profile.sh is a symlink)
|
||||||
|
# Because we're more likely to be sourced, we use BASH_SOURCE to get the path
|
||||||
|
# of the sourced file instead of $0
|
||||||
|
if [[ -z "$PROFILE_PATH" ]]; then
|
||||||
|
export MYPATH=$(dirname "$(realpath -s "${BASH_SOURCE[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
|
# Build PATH environment variable
|
||||||
if [[ $EUID -eq 0 ]]; then
|
if [[ $EUID -eq 0 ]]; then
|
||||||
pathappend /sbin:/usr/sbin
|
pathappend /sbin:/usr/sbin
|
||||||
fi
|
fi
|
||||||
[[ -d /share/services/gestparc ]] && pathappend /share/services/gestparc
|
|
||||||
[[ -d ~/bin ]] && pathappend ~/bin
|
[[ -d ~/bin ]] && pathappend ~/bin
|
||||||
[[ -d ~/.local/bin ]] && pathappend ~/.local/bin
|
[[ -d ~/.local/bin ]] && pathappend ~/.local/bin
|
||||||
|
|
||||||
# Set bash history
|
# Parse and load general configuration
|
||||||
export HISTSIZE=50000
|
export PROFILE_CONF="$MYPATH/profile.conf"
|
||||||
export HISTIGNORE="&:[bf]g:exit"
|
parse_conf "$PROFILE_CONF"
|
||||||
|
load_conf system # Load Bash system behavior configuration (history, pager, etc.)
|
||||||
|
load_conf general # General purpose configuration (compilation flags, etc.)
|
||||||
|
|
||||||
# Set default pager
|
# Load module scripts
|
||||||
export PAGER=less
|
for script in $MYPATH/profile.d/*.sh; do
|
||||||
|
if [[ -r $script ]]; then
|
||||||
# More colors
|
|
||||||
export TERM=xterm-256color
|
|
||||||
|
|
||||||
# Set some compiling values
|
|
||||||
export CFLAGS="-O2 -pipe -march=native"
|
|
||||||
export MAKEFLAGS='-j12'
|
|
||||||
export PKGSOURCES='/share/src/archives'
|
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# Default values could be altered after this line
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# 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
|
|
||||||
. $script
|
. $script
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -124,34 +232,12 @@ done
|
|||||||
# Interactive shell detection, two methods available each one of those might have different result
|
# Interactive shell detection, two methods available each one of those might have different result
|
||||||
# depending on distribution
|
# depending on distribution
|
||||||
#shopt -q login_shell && INTERACTIVE=1
|
#shopt -q login_shell && INTERACTIVE=1
|
||||||
[[ $- == *i* ]] && INTERACTIVE=1
|
[[ $- == *i* ]] && export INTERACTIVE=1
|
||||||
|
|
||||||
if [[ $INTERACTIVE ]]; then
|
if [[ $INTERACTIVE ]]; then
|
||||||
# For compiling (as we often compile with LFS/0linux...)
|
# For compiling (as we often compile with LFS/0linux...)
|
||||||
#Aliases
|
#Aliases
|
||||||
alias ll='ls -laFh --color=auto'
|
load_alias aliases
|
||||||
alias la='ls -Ah --color=auto'
|
|
||||||
alias l='ls -CF --color=auto'
|
|
||||||
alias ls='ls --color=auto'
|
|
||||||
|
|
||||||
alias grep='grep --color=auto'
|
|
||||||
alias egrep='egrep --color=auto'
|
|
||||||
alias fgrep='fgrep --color=auto'
|
|
||||||
alias qfind="find . -name "
|
|
||||||
|
|
||||||
alias mkck='make check'
|
|
||||||
alias mkin='make install'
|
|
||||||
alias mkdin='make DESTDIR=$PWD/dest-install install'
|
|
||||||
alias ssh='ssh -Y'
|
|
||||||
|
|
||||||
alias wget='wget -c' # resume mode by default
|
|
||||||
alias myip='curl ip.appspot.com'
|
|
||||||
|
|
||||||
# Human readable by default
|
|
||||||
alias df='df -H'
|
|
||||||
alias du='du -ch'
|
|
||||||
|
|
||||||
alias sdu='du -sk ./* | sort -n'
|
|
||||||
|
|
||||||
# Define PS1
|
# Define PS1
|
||||||
trap 'timer_start' DEBUG
|
trap 'timer_start' DEBUG
|
||||||
@@ -159,7 +245,8 @@ if [[ $INTERACTIVE ]]; then
|
|||||||
|
|
||||||
# Set default language
|
# Set default language
|
||||||
setfr
|
setfr
|
||||||
showinfo
|
showinfo && printf "\n"
|
||||||
|
check_updates -q
|
||||||
disp I "Profile version $PROFVERSION chargé..."
|
disp I "Profile version $PROFVERSION chargé..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user