Compare commits
30 Commits
bc0a592fa1
...
v4.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1225230a07 | ||
|
|
9c43190202 | ||
|
|
9477638a28 | ||
|
|
f16ad711fb | ||
|
|
15ef317029 | ||
|
|
a6e4d7a256 | ||
|
|
6106ca7684 | ||
|
|
1088029ae6 | ||
|
|
eb4c89759b | ||
|
|
1dc5d72ac6 | ||
|
|
d49703c5d5 | ||
|
|
066f2e353e | ||
|
|
c011f03aee | ||
|
|
c4b0516c45 | ||
|
|
4da29872fc | ||
|
|
d7a0e2c5f5 | ||
|
|
d60a93814b | ||
|
|
d27935eedd | ||
|
|
e77232b3ca | ||
|
|
d6dce2d91e | ||
|
|
4e3cccff64 | ||
|
|
91f033743d | ||
|
|
9fcf21c55e | ||
|
|
5300386941 | ||
|
|
dfad345be3 | ||
|
|
1b16878ea8 | ||
|
|
30b8b8241a | ||
|
|
a4056b9e82 | ||
|
|
6696e0d05a | ||
|
|
6d15af029e |
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# User-specific configuration — never commit personal settings.
|
||||||
|
# Copy doc/profile.conf.example to profile.conf and customise it.
|
||||||
|
profile.conf
|
||||||
|
|
||||||
|
# Compiled / generated artefacts
|
||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
# macOS noise
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Editor swap / backup files
|
||||||
|
*~
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
Copyright 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
|
|
||||||
This is distributed with BSD-3-Clause license with the following terms and
|
This is distributed with BSD-3-Clause license with the following terms and
|
||||||
condition:
|
condition:
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -68,7 +68,8 @@ A bar-style prompt showing current time, execution time of the last command
|
|||||||
| `mcd` | filefct | Create a directory and immediately move into it |
|
| `mcd` | filefct | Create a directory and immediately move into it |
|
||||||
| `meteo` | info | Display weather forecast for the configured or given city |
|
| `meteo` | info | Display weather forecast for the configured or given city |
|
||||||
| `myextip` | net | Get information about your public IP address |
|
| `myextip` | net | Get information about your public IP address |
|
||||||
| `pkgs` | packages | Search for a pattern in installed package names (dpkg/rpm, supports `-i`) |
|
| `get_pkgmgr` | packages | Detect the active package manager of the running distribution (`apt`, `dnf`, `yum`, `zypper`, `pacman`, `apk`, `portage`, `xbps`, `nix`) |
|
||||||
|
| `pkgs` | packages | Search for a pattern in installed package names (distro-aware via `get_pkgmgr`, supports `-i`) |
|
||||||
| `ppg` | processes | Look for the given pattern in running processes |
|
| `ppg` | processes | Look for the given pattern in running processes |
|
||||||
| `ppn` | processes | List processes matching an exact command name |
|
| `ppn` | processes | List processes matching an exact command name |
|
||||||
| `ppu` | processes | List processes owned by a specific user |
|
| `ppu` | processes | List processes owned by a specific user |
|
||||||
@@ -204,7 +205,7 @@ change the default without having to pass flags every time.
|
|||||||
|
|
||||||
### 4.3. Locale shortcuts
|
### 4.3. Locale shortcuts
|
||||||
|
|
||||||
The `[general]` key `SET_LOCALE` accepts a comma-separated list of
|
The `[lang]` key `SET_LOCALE` accepts a comma-separated list of
|
||||||
`alias:locale` pairs. Each pair generates a function of that name at startup:
|
`alias:locale` pairs. Each pair generates a function of that name at startup:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
@@ -214,6 +215,16 @@ SET_LOCALE = fr:fr_FR.UTF-8, us:en_US.UTF-8
|
|||||||
This creates `setfr` and `setus`. Use `setlocale <locale>` to switch to any
|
This creates `setfr` and `setus`. Use `setlocale <locale>` to switch to any
|
||||||
installed locale directly.
|
installed locale directly.
|
||||||
|
|
||||||
|
Set `DEFAULT_LANG` to one of the defined aliases to activate that locale
|
||||||
|
automatically at login:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
DEFAULT_LANG = fr
|
||||||
|
```
|
||||||
|
|
||||||
|
If `DEFAULT_LANG` is set but does not match any alias in `SET_LOCALE`, a
|
||||||
|
warning is displayed and no locale change is applied.
|
||||||
|
|
||||||
### 4.4. Prompt theming
|
### 4.4. Prompt theming
|
||||||
|
|
||||||
The prompt appearance is controlled by two mechanisms that are applied in order
|
The prompt appearance is controlled by two mechanisms that are applied in order
|
||||||
|
|||||||
@@ -7,6 +7,32 @@ Versions follow `MAJOR.MINOR.PATCH-REVISION_STAGE_N` (e.g. `3.99.1-4_rc_1`).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [3.99.2-4_rc_2] — 2026-04-21
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **`prompt.sh`** — `\$Last_Command` in PS1 was escaped, preventing the exit
|
||||||
|
code from ever appearing in the prompt (the local variable no longer exists
|
||||||
|
when PS1 is rendered by bash). Removed the backslash so the value is embedded
|
||||||
|
at `set_prompt` build time.
|
||||||
|
- **`filefct.sh` — `file_stats()`** — a stray unconditional `shift` after
|
||||||
|
`esac` doubled-shifted arguments already shifted by each `case` branch;
|
||||||
|
successive options such as `-H -d` were silently skipped.
|
||||||
|
- **`packages.sh` — `pkgs()`** — replaced the unreliable binary-presence test
|
||||||
|
(`command -v dpkg / rpm`) with the new `get_pkgmgr` function. Also corrected
|
||||||
|
a typo in the "no package manager" error message (`avialable` → `available`).
|
||||||
|
- **`processes.sh` — `kt()`** — copy-paste error: usage error message read
|
||||||
|
`"Usage: ppg <string>"` instead of `"Usage: kt <pid>"`.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- **`packages.sh` — `get_pkgmgr()`** — new exported helper that detects the
|
||||||
|
active package manager of the running distribution. Detection first reads
|
||||||
|
`/etc/os-release` (`ID` then `ID_LIKE`), then falls back to a
|
||||||
|
fixed-priority binary scan. Supported families: `apt`, `dnf`, `yum`,
|
||||||
|
`zypper`, `pacman`, `apk`, `portage`, `xbps`, `nix`. Returns 1 when
|
||||||
|
nothing is identified. Available to all future commands in `packages.sh`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [3.99.1-4_rc_1] — 2026
|
## [3.99.1-4_rc_1] — 2026
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -29,9 +29,48 @@ to target). Stale forks cause avoidable merge conflicts.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Development environment
|
## 3. Branch policy
|
||||||
|
|
||||||
| Requirement | Minimum version | Notes |
|
| Branch | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `master` | Main development branch — new features and enhancements go here |
|
||||||
|
| `<version>` (e.g. `3.x`) | Maintenance branch for a released version — bugfixes backported from `master` |
|
||||||
|
|
||||||
|
**New functionality** must always target `master`.
|
||||||
|
|
||||||
|
**Bugfixes** must target the branch where the bug was introduced:
|
||||||
|
- If the bug exists in a released version, open the fix against that version's
|
||||||
|
maintenance branch first, then cherry-pick onto `master`.
|
||||||
|
- If the bug is only in `master` (unreleased), fix it directly on `master`.
|
||||||
|
- During a release-candidate cycle, bugfixes go on the `x.*` branch and are
|
||||||
|
merged back into `master` before the final release.
|
||||||
|
|
||||||
|
Do **not** add new features to a maintenance branch.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Versioning scheme
|
||||||
|
|
||||||
|
Versions follow the format **`MAJOR.MINOR.PATCH`** where the `MINOR` number
|
||||||
|
conveys the development stage of the next major release:
|
||||||
|
|
||||||
|
| Minor range | Stage | Rules |
|
||||||
|
|---|---|---|
|
||||||
|
| `x.90.y` | **Alpha** toward `x+1` | Stays on `master`. Development is open: new features are welcome, regressions are acceptable. |
|
||||||
|
| `x.95.y` | **Beta** toward `x+1` | The `x+1.*` maintenance branch is created at this point. No regression unless absolutely necessary; new features still allowed. |
|
||||||
|
| `x.99.y` | **RC** toward `x+1` | Bugfixes only. No new features. No regression allowed. Becomes `x+1.0.0` when stable. |
|
||||||
|
|
||||||
|
Examples: `3.90.1` is the first alpha toward `4.0`, `3.99.2` is the second
|
||||||
|
release candidate for `4.0`.
|
||||||
|
|
||||||
|
The `PATCH` number increments freely within a stage. A bump in `MINOR`
|
||||||
|
(e.g. `90` → `95`) always indicates a stage promotion in development phase.
|
||||||
|
|
||||||
|
Any experimental version must have it's dedicated branch.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Development environment
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Bash | 4.3 | Namerefs (`local -n`) required |
|
| Bash | 4.3 | Namerefs (`local -n`) required |
|
||||||
| shellcheck | any recent | Run before every commit |
|
| shellcheck | any recent | Run before every commit |
|
||||||
@@ -52,7 +91,7 @@ brew install shellcheck
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Code style
|
## 6. Code style
|
||||||
|
|
||||||
### General rules
|
### General rules
|
||||||
- **Bash only** — no external interpreters in core modules. Python or Perl is
|
- **Bash only** — no external interpreters in core modules. Python or Perl is
|
||||||
@@ -62,8 +101,8 @@ brew install shellcheck
|
|||||||
- **`[[ … ]]`** for all conditionals — not `[ … ]`.
|
- **`[[ … ]]`** for all conditionals — not `[ … ]`.
|
||||||
- **`(( … ))`** for arithmetic — not `$(( … ))` in conditionals.
|
- **`(( … ))`** for arithmetic — not `$(( … ))` in conditionals.
|
||||||
- **`local`** for all function-internal variables — avoid polluting the
|
- **`local`** for all function-internal variables — avoid polluting the
|
||||||
environment.
|
environment. Prefer upper case for global and lowercase for local.
|
||||||
- **`printf`** instead of `echo` wherever the format matters.
|
- **`printf`** instead of `echo` all the time.
|
||||||
- **Never `eval`** — use namerefs (`local -n`), `${!varname}` indirection, or
|
- **Never `eval`** — use namerefs (`local -n`), `${!varname}` indirection, or
|
||||||
`declare -g` instead.
|
`declare -g` instead.
|
||||||
- **No hardcoded defaults** — wire every configurable value through
|
- **No hardcoded defaults** — wire every configurable value through
|
||||||
@@ -100,7 +139,7 @@ Add the `load_conf` call near the top after any variable declarations.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Configuration keys
|
## 7. Configuration keys
|
||||||
|
|
||||||
When adding a configurable default:
|
When adding a configurable default:
|
||||||
|
|
||||||
@@ -110,7 +149,7 @@ When adding a configurable default:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. Theming
|
## 8. Theming
|
||||||
|
|
||||||
New theme files go in `profile.d/themes/` with a `.theme` extension.
|
New theme files go in `profile.d/themes/` with a `.theme` extension.
|
||||||
They are **parsed, not executed** — do not add shell logic.
|
They are **parsed, not executed** — do not add shell logic.
|
||||||
@@ -118,7 +157,7 @@ See the existing themes and `README.md §4.4` for the allowed syntax.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. Running shellcheck
|
## 9. Running shellcheck
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
shellcheck -x profile.sh profile.d/*.sh
|
shellcheck -x profile.sh profile.d/*.sh
|
||||||
@@ -130,7 +169,7 @@ comment explaining why the suppression is necessary.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. Submitting a contribution
|
## 10. Submitting a contribution
|
||||||
|
|
||||||
### Via Git (preferred)
|
### Via Git (preferred)
|
||||||
1. Contact the maintainer to obtain push access, or fork on the Gitea instance.
|
1. Contact the maintainer to obtain push access, or fork on the Gitea instance.
|
||||||
@@ -156,7 +195,7 @@ Reference issue numbers if applicable: closes #42.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. What will be rejected
|
## 11. What will be rejected
|
||||||
|
|
||||||
- Code requiring packages not in a minimal Debian or CentOS install.
|
- Code requiring packages not in a minimal Debian or CentOS install.
|
||||||
- Use of `eval`, `source`-based config loading, or other code-injection vectors.
|
- Use of `eval`, `source`-based config loading, or other code-injection vectors.
|
||||||
@@ -166,6 +205,6 @@ Reference issue numbers if applicable: closes #42.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. Financial contributions
|
## 12. Financial contributions
|
||||||
|
|
||||||
Contact the maintainer by mail if you wish to make a financial contribution.
|
Contact the maintainer by mail if you wish to make a financial contribution.
|
||||||
|
|||||||
29
doc/LICENSE
Executable file
29
doc/LICENSE
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
Copyright 2021-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
||||||
|
|
||||||
|
This software is distributed under the BSD-3-Clause license with the
|
||||||
|
following terms and conditions:
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its 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 HOLDER 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, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
@@ -89,6 +89,11 @@ TERM=xterm-256color
|
|||||||
# creates setfr, setus, setes.
|
# creates setfr, setus, setes.
|
||||||
#SET_LOCALE=fr:fr_FR.UTF-8,us:en_US.UTF-8
|
#SET_LOCALE=fr:fr_FR.UTF-8,us:en_US.UTF-8
|
||||||
|
|
||||||
|
# Alias to activate at login. Must match one of the aliases defined in SET_LOCALE above.
|
||||||
|
# Example: DEFAULT_LANG=fr → calls setfr at startup.
|
||||||
|
# Leave unset to keep the system default locale.
|
||||||
|
#DEFAULT_LANG=fr
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
[net]
|
[net]
|
||||||
# dwl: Force a specific download tool (curl, wget, fetch).
|
# dwl: Force a specific download tool (curl, wget, fetch).
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ version-bump.
|
|||||||
- [ ] **Bash completion** — add a `profile.d/completion/` directory and write
|
- [ ] **Bash completion** — add a `profile.d/completion/` directory and write
|
||||||
`_profile_upgrade`, `_taz`, `_utaz`, `_meteo`, etc. completions so that
|
`_profile_upgrade`, `_taz`, `_utaz`, `_meteo`, etc. completions so that
|
||||||
`<Tab>` works on all public functions. **[medium]**
|
`<Tab>` works on all public functions. **[medium]**
|
||||||
- [ ] **`shellcheck` clean pass** — run `shellcheck -x profile.sh profile.d/*.sh`
|
|
||||||
and address every remaining warning (currently a handful of SC2034 and SC2086
|
|
||||||
items). Integrate as a pre-commit hook. **[easy]**
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -70,10 +67,6 @@ version-bump.
|
|||||||
(configurable via `MYEXTIP_FALLBACK_URL`) when the primary times out.
|
(configurable via `MYEXTIP_FALLBACK_URL`) when the primary times out.
|
||||||
**[easy]**
|
**[easy]**
|
||||||
|
|
||||||
### packages
|
|
||||||
- [ ] **Additional backends** — add support for `pacman` (Arch), `apk` (Alpine),
|
|
||||||
`xbps-query` (Void), and `brew` (macOS). **[medium]**
|
|
||||||
|
|
||||||
### processes
|
### processes
|
||||||
- [ ] **`ku` dry-run flag** — add `-n` / `--dry-run` to print what would be
|
- [ ] **`ku` dry-run flag** — add `-n` / `--dry-run` to print what would be
|
||||||
killed without acting. **[easy]**
|
killed without acting. **[easy]**
|
||||||
|
|||||||
@@ -44,36 +44,42 @@
|
|||||||
# -n, --no-dir Never create a host directory
|
# -n, --no-dir Never create a host directory
|
||||||
utaz()
|
utaz()
|
||||||
{
|
{
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_ununzip()
|
_ununzip()
|
||||||
{
|
{
|
||||||
unzip -o "$1" -d "$2" >/dev/null 2>&1
|
unzip -o "$1" -d "$2" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_untar()
|
_untar()
|
||||||
{
|
{
|
||||||
tar -xf "$1" -C "$2"
|
tar -xf "$1" -C "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_ungzip()
|
_ungzip()
|
||||||
{
|
{
|
||||||
tar -xzf "$1" -C "$2"
|
tar -xzf "$1" -C "$2"
|
||||||
}
|
}
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_unbzip2()
|
_unbzip2()
|
||||||
{
|
{
|
||||||
tar -xjf "$1" -C "$2"
|
tar -xjf "$1" -C "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_unxz()
|
_unxz()
|
||||||
{
|
{
|
||||||
tar -xJf "$1" -C "$2"
|
tar -xJf "$1" -C "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_unlzop()
|
_unlzop()
|
||||||
{
|
{
|
||||||
lzop -d "$1" -o "$2/$(basename "${1%.*}")"
|
lzop -d "$1" -o "$2/$(basename "${1%.*}")"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_unlzip()
|
_unlzip()
|
||||||
{
|
{
|
||||||
if command -v plzip >/dev/null 2>&1; then
|
if command -v plzip >/dev/null 2>&1; then
|
||||||
@@ -83,16 +89,19 @@ utaz()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_ununrar()
|
_ununrar()
|
||||||
{
|
{
|
||||||
unrar x -o+ "$1" "$2/" >/dev/null 2>&1
|
unrar x -o+ "$1" "$2/" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_ununarj()
|
_ununarj()
|
||||||
{
|
{
|
||||||
unarj e "$1" "$2/" >/dev/null 2>&1
|
unarj e "$1" "$2/" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_unlha()
|
_unlha()
|
||||||
{
|
{
|
||||||
# lha typically extracts into the current directory
|
# lha typically extracts into the current directory
|
||||||
@@ -100,40 +109,47 @@ utaz()
|
|||||||
(cd "$2" && lha -x "../$1") >/dev/null 2>&1
|
(cd "$2" && lha -x "../$1") >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_ununace()
|
_ununace()
|
||||||
{
|
{
|
||||||
unace x "$1" "$2/" >/dev/null 2>&1
|
unace x "$1" "$2/" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_un7z()
|
_un7z()
|
||||||
{
|
{
|
||||||
7z x "$1" -o"$2/" >/dev/null 2>&1
|
7z x "$1" -o"$2/" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_unzstd()
|
_unzstd()
|
||||||
{
|
{
|
||||||
# Zstd decompresses files directly, often requiring tar for archives
|
# Zstd decompresses files directly, often requiring tar for archives
|
||||||
tar --zstd -xf "$1" -C "$2"
|
tar --zstd -xf "$1" -C "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_uncpio()
|
_uncpio()
|
||||||
{
|
{
|
||||||
# CPIO requires careful directory handling
|
# CPIO requires careful directory handling
|
||||||
(cd "$2" && cpio -id < "../$1") >/dev/null 2>&1
|
(cd "$2" && cpio -id < "../$1") >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_uncabextract()
|
_uncabextract()
|
||||||
{
|
{
|
||||||
# Requires 'cabextract' package
|
# Requires 'cabextract' package
|
||||||
cabextract "$1" -d "$2/" >/dev/null 2>&1
|
cabextract "$1" -d "$2/" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_undeb()
|
_undeb()
|
||||||
{
|
{
|
||||||
# Extracts data content from a Debian package
|
# Extracts data content from a Debian package
|
||||||
dpkg-deb -x "$1" "$2/" >/dev/null 2>&1
|
dpkg-deb -x "$1" "$2/" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_unrpm()
|
_unrpm()
|
||||||
{
|
{
|
||||||
# Extracts CPIO-based payload from an RPM package
|
# Extracts CPIO-based payload from an RPM package
|
||||||
@@ -141,8 +157,9 @@ utaz()
|
|||||||
rpm2cpio "$1" | (cd "$2/" && cpio -idmv) >/dev/null 2>&1
|
rpm2cpio "$1" | (cd "$2/" && cpio -idmv) >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
local PARSED=$(getopt -o hdcn --long help,delete,create-dir,no-dir -n 'utaz' -- "$@")
|
local PARSED
|
||||||
|
PARSED=$(getopt -o hdcn --long help,delete,create-dir,no-dir -n 'utaz' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
disp E "Invalid options, use \"utaz --help\" to display usage."
|
disp E "Invalid options, use \"utaz --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -314,10 +331,10 @@ utaz()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
disp I "Processing archive ${f} with ${extractor}..."
|
disp I "Processing archive ${f} with ${extractor}..."
|
||||||
mkdir -p "${dir}"
|
if ! mkdir -p "${dir}"; then
|
||||||
[[ $? -gt 0 ]] &&
|
|
||||||
disp E "The filesystem can't create directories, exit!" &&
|
disp E "The filesystem can't create directories, exit!" &&
|
||||||
return 1
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
${extractor} "${f}" "${dir}"
|
${extractor} "${f}" "${dir}"
|
||||||
case $? in
|
case $? in
|
||||||
@@ -390,6 +407,7 @@ export -f utaz
|
|||||||
# -1, .., -9 Compression level to use [1=fast/biggest, 9=slow/smallest]
|
# -1, .., -9 Compression level to use [1=fast/biggest, 9=slow/smallest]
|
||||||
taz()
|
taz()
|
||||||
{
|
{
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_doxz()
|
_doxz()
|
||||||
{
|
{
|
||||||
command -v xz >/dev/null 2>&1 || {
|
command -v xz >/dev/null 2>&1 || {
|
||||||
@@ -397,17 +415,19 @@ taz()
|
|||||||
return 127
|
return 127
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ $4 ]] && local verb='-v'
|
local verb=()
|
||||||
|
[[ $4 ]] && verb=('-v')
|
||||||
|
|
||||||
# Display a warning for this format
|
# Display a warning for this format
|
||||||
disp W "xz format is not suited for long term archiving."
|
disp W "xz format is not suited for long term archiving."
|
||||||
disp I "See https://www.nongnu.org/lzip/xz_inadequate.html for details."
|
disp I "See https://www.nongnu.org/lzip/xz_inadequate.html for details."
|
||||||
|
|
||||||
# Compresse to xz (lzma2) - Deprecated
|
# Compress with xz (lzma2) - Deprecated
|
||||||
xz $verb --compress --keep -$3 -T $2 $1
|
xz "${verb[@]}" --compress --keep "-$3" -T "$2" "$1"
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_dolz()
|
_dolz()
|
||||||
{
|
{
|
||||||
local procopt="--threads $2"
|
local procopt="--threads $2"
|
||||||
@@ -425,13 +445,16 @@ taz()
|
|||||||
disp W "Consider installing plzip to obtain multithreading abilities."
|
disp W "Consider installing plzip to obtain multithreading abilities."
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ $4 ]] && local verb="-vv"
|
local opt=()
|
||||||
|
[[ $4 ]] && opt=('-vv')
|
||||||
|
opt+=("$procopt")
|
||||||
|
|
||||||
# Compresse au format lzip (lzma)
|
# Compress with lzip (lzma)
|
||||||
$command $verb $procopt --keep -$3 $1
|
$command "${opt[@]}" --keep "-$3" "$1"
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_dogz()
|
_dogz()
|
||||||
{
|
{
|
||||||
local procopt="--processes $2"
|
local procopt="--processes $2"
|
||||||
@@ -449,13 +472,16 @@ taz()
|
|||||||
disp W "Consider installing pigz to obtain multithreading abilities."
|
disp W "Consider installing pigz to obtain multithreading abilities."
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ $4 ]] && local verb="--verbose"
|
local opt=()
|
||||||
|
[[ $4 ]] && opt=('--verbose')
|
||||||
|
opt+=("$procopt")
|
||||||
|
|
||||||
# Compresse au format bz2
|
# Compresse au format bz2
|
||||||
$command $verb $procopt --keep -$3 $1
|
$command "${opt[@]}" --keep "-$3" "$1"
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_dobz2()
|
_dobz2()
|
||||||
{
|
{
|
||||||
local procopt="-p$2"
|
local procopt="-p$2"
|
||||||
@@ -473,13 +499,16 @@ taz()
|
|||||||
disp W "Consider installing pbzip2 to obtain multithreading abilities."
|
disp W "Consider installing pbzip2 to obtain multithreading abilities."
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ $4 ]] && local verb="-v"
|
local opt=()
|
||||||
|
[[ $4 ]] && opt=('-v')
|
||||||
|
opt+=("$procopt")
|
||||||
|
|
||||||
# Compresse au format bz2
|
# Compress with bz2
|
||||||
$command $verb --compress $procopt --keep -$3 $1
|
$command "${opt[@]}" --compress --keep "-$3" "$1"
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
_dolzo()
|
_dolzo()
|
||||||
{
|
{
|
||||||
command -v lzop >/dev/null 2>&1 || {
|
command -v lzop >/dev/null 2>&1 || {
|
||||||
@@ -487,16 +516,18 @@ taz()
|
|||||||
return 127
|
return 127
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ $4 ]] && local verb='-v'
|
local verb=()
|
||||||
|
[[ $4 ]] && verb=('-v')
|
||||||
[[ $2 -gt 1 ]] && disp W "lzop doesn't support multithreading, falling back to 1 thread."
|
[[ $2 -gt 1 ]] && disp W "lzop doesn't support multithreading, falling back to 1 thread."
|
||||||
|
|
||||||
# Compresse au format lzo
|
# Compresse au format lzo
|
||||||
lzop --keep -$3 $1
|
lzop "${verb[@]}" --keep "-$3" "$1"
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
local PARSED
|
local PARSED
|
||||||
PARSED=$(getopt -o hdf:p:vq123456789 --long help,delete,format:,parallel:,verbose,quiet --name "taz" -- "$@")
|
PARSED=$(getopt -o hdf:p:vq123456789 --long help,delete,format:,parallel:,verbose,quiet --name "taz" -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
disp E "Invalid options, use \"taz --help\" to display usage."
|
disp E "Invalid options, use \"taz --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -587,8 +618,7 @@ taz()
|
|||||||
if [[ -d "$item" ]]; then
|
if [[ -d "$item" ]]; then
|
||||||
disp I "\t Creating $item.tar... "
|
disp I "\t Creating $item.tar... "
|
||||||
|
|
||||||
tar -cf "$item.tar" "$item"
|
if ! tar -cf "$item.tar" "$item"; 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
|
||||||
fi
|
fi
|
||||||
@@ -602,8 +632,9 @@ 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"
|
local exec_code=0
|
||||||
[[ ! $? -eq 0 ]] && case $? in
|
"_do$compform" "$fname" "$nproc" "$complevel" "$verbose" || exec_code=$?
|
||||||
|
[[ ! $exec_code -eq 0 ]] && case $exec_code in
|
||||||
127)
|
127)
|
||||||
disp E "Compression program unavailable, aborting."
|
disp E "Compression program unavailable, aborting."
|
||||||
return 127
|
return 127
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ settrace()
|
|||||||
|
|
||||||
local PARSED
|
local PARSED
|
||||||
PARSED=$(getopt -oh --long help,on,off,status,force -- "$@")
|
PARSED=$(getopt -oh --long help,on,off,status,force -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"settrace --help\" to display usage."
|
disp E "Invalid options, use \"settrace --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -36,81 +36,85 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Color definitions
|
# Color definitions
|
||||||
# Standard 16 colors display declaration
|
set_colors()
|
||||||
export DEFAULTFG='\e[0;39m'
|
{
|
||||||
export DEFAULTBG='\e[0;49m'
|
# Standard 16 colors display declaration
|
||||||
export DEFAULTCOL="${DEFAULTBG}${DEFAULTFG}"
|
export DEFAULTFG='\e[0;39m'
|
||||||
export RESETCOL=$'\e[0m'
|
export DEFAULTBG='\e[0;49m'
|
||||||
|
export DEFAULTCOL="${DEFAULTBG}${DEFAULTFG}"
|
||||||
|
export RESETCOL=$'\e[0m'
|
||||||
|
|
||||||
# Regular Colors
|
# Regular Colors
|
||||||
export Black='\e[0;30m'
|
export Black='\e[0;30m'
|
||||||
export Red='\e[0;31m'
|
export Red='\e[0;31m'
|
||||||
export Green='\e[0;32m'
|
export Green='\e[0;32m'
|
||||||
export Yellow='\e[0;33m'
|
export Yellow='\e[0;33m'
|
||||||
export Blue='\e[0;34m'
|
export Blue='\e[0;34m'
|
||||||
export Purple='\e[0;35m'
|
export Purple='\e[0;35m'
|
||||||
export Cyan='\e[0;36m'
|
export Cyan='\e[0;36m'
|
||||||
export White='\e[0;37m'
|
export White='\e[0;37m'
|
||||||
|
|
||||||
# Bold
|
# Bold
|
||||||
export BBlack='\e[1;30m'
|
export BBlack='\e[1;30m'
|
||||||
export BRed='\e[1;31m'
|
export BRed='\e[1;31m'
|
||||||
export BGreen='\e[1;32m'
|
export BGreen='\e[1;32m'
|
||||||
export BYellow='\e[1;33m'
|
export BYellow='\e[1;33m'
|
||||||
export BBlue='\e[1;34m'
|
export BBlue='\e[1;34m'
|
||||||
export BPurple='\e[1;35m'
|
export BPurple='\e[1;35m'
|
||||||
export BCyan='\e[1;36m'
|
export BCyan='\e[1;36m'
|
||||||
export BWhite='\e[1;37m'
|
export BWhite='\e[1;37m'
|
||||||
|
|
||||||
# Underline
|
# Underline
|
||||||
export UBlack='\e[4;30m'
|
export UBlack='\e[4;30m'
|
||||||
export URed='\e[4;31m'
|
export URed='\e[4;31m'
|
||||||
export UGreen='\e[4;32m'
|
export UGreen='\e[4;32m'
|
||||||
export UYellow='\e[4;33m'
|
export UYellow='\e[4;33m'
|
||||||
export UBlue='\e[4;34m'
|
export UBlue='\e[4;34m'
|
||||||
export UPurple='\e[4;35m'
|
export UPurple='\e[4;35m'
|
||||||
export UCyan='\e[4;36m'
|
export UCyan='\e[4;36m'
|
||||||
export UWhite='\e[4;37m'
|
export UWhite='\e[4;37m'
|
||||||
|
|
||||||
# Background
|
# Background
|
||||||
export On_Black='\e[40m'
|
export On_Black='\e[40m'
|
||||||
export On_Red='\e[41m'
|
export On_Red='\e[41m'
|
||||||
export On_Green='\e[42m'
|
export On_Green='\e[42m'
|
||||||
export On_Yellow='\e[43m'
|
export On_Yellow='\e[43m'
|
||||||
export On_Blue='\e[44m'
|
export On_Blue='\e[44m'
|
||||||
export On_Purple='\e[45m'
|
export On_Purple='\e[45m'
|
||||||
export On_Cyan='\e[46m'
|
export On_Cyan='\e[46m'
|
||||||
export On_White='\e[47m'
|
export On_White='\e[47m'
|
||||||
|
|
||||||
# High Intensity
|
# High Intensity
|
||||||
export IBlack='\e[0;90m'
|
export IBlack='\e[0;90m'
|
||||||
export IRed='\e[0;91m'
|
export IRed='\e[0;91m'
|
||||||
export IGreen='\e[0;92m'
|
export IGreen='\e[0;92m'
|
||||||
export IYellow='\e[0;93m'
|
export IYellow='\e[0;93m'
|
||||||
export IBlue='\e[0;94m'
|
export IBlue='\e[0;94m'
|
||||||
export IPurple='\e[0;95m'
|
export IPurple='\e[0;95m'
|
||||||
export ICyan='\e[0;96m'
|
export ICyan='\e[0;96m'
|
||||||
export IWhite='\e[0;97m'
|
export IWhite='\e[0;97m'
|
||||||
|
|
||||||
# Bold High Intensity
|
# Bold High Intensity
|
||||||
export BIBlack='\e[1;90m'
|
export BIBlack='\e[1;90m'
|
||||||
export BIRed='\e[1;91m'
|
export BIRed='\e[1;91m'
|
||||||
export BIGreen='\e[1;92m'
|
export BIGreen='\e[1;92m'
|
||||||
export BIYellow='\e[1;93m'
|
export BIYellow='\e[1;93m'
|
||||||
export BIBlue='\e[1;94m'
|
export BIBlue='\e[1;94m'
|
||||||
export BIPurple='\e[1;95m'
|
export BIPurple='\e[1;95m'
|
||||||
export BICyan='\e[1;96m'
|
export BICyan='\e[1;96m'
|
||||||
export BIWhite='\e[1;97m'
|
export BIWhite='\e[1;97m'
|
||||||
|
|
||||||
# High Intensity backgrounds
|
# High Intensity backgrounds
|
||||||
export On_IBlack='\e[0;100m'
|
export On_IBlack='\e[0;100m'
|
||||||
export On_IRed='\e[0;101m'
|
export On_IRed='\e[0;101m'
|
||||||
export On_IGreen='\e[0;102m'
|
export On_IGreen='\e[0;102m'
|
||||||
export On_IYellow='\e[0;103m'
|
export On_IYellow='\e[0;103m'
|
||||||
export On_IBlue='\e[0;104m'
|
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'
|
||||||
|
}
|
||||||
|
export -f set_colors
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@@ -179,5 +183,6 @@ export -f disp
|
|||||||
|
|
||||||
# Load disp section variables
|
# Load disp section variables
|
||||||
load_conf disp
|
load_conf disp
|
||||||
|
set_colors
|
||||||
|
|
||||||
# EOF
|
# EOF
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ expandlist()
|
|||||||
{
|
{
|
||||||
local separator="${EXPANDLIST_DEFAULT_SEPARATOR:- }"
|
local separator="${EXPANDLIST_DEFAULT_SEPARATOR:- }"
|
||||||
local PARSED
|
local PARSED
|
||||||
|
|
||||||
PARSED=$(getopt -o hs:n --long help,separator:,newline -n 'expandlist' -- "$@")
|
PARSED=$(getopt -o hs:n --long help,separator:,newline -n 'expandlist' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"expandlist --help\" to display usage."
|
disp E "Invalid options, use \"expandlist --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -87,6 +87,7 @@ expandlist()
|
|||||||
|
|
||||||
# True glob expansion when wildcards are present.
|
# True glob expansion when wildcards are present.
|
||||||
if [[ "$item" == *'*'* || "$item" == *'?'* || "$item" == *'['* ]]; then
|
if [[ "$item" == *'*'* || "$item" == *'?'* || "$item" == *'['* ]]; then
|
||||||
|
# shellcheck disable=SC2206 # We actually want the word splitting
|
||||||
expanded=( $item )
|
expanded=( $item )
|
||||||
else
|
else
|
||||||
expanded=( "$item" )
|
expanded=( "$item" )
|
||||||
@@ -127,7 +128,7 @@ clean()
|
|||||||
# Define short and long options
|
# Define short and long options
|
||||||
local PARSED
|
local PARSED
|
||||||
PARSED=$(getopt -o hrsf --long help,recurs,shell,force -n 'clean' -- "$@")
|
PARSED=$(getopt -o hrsf --long help,recurs,shell,force -n 'clean' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"clean --help\" to display usage."
|
disp E "Invalid options, use \"clean --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -215,10 +216,14 @@ mcd()
|
|||||||
disp E "Missing parameter. Use \"mcd --help\" to display usage."
|
disp E "Missing parameter. Use \"mcd --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
mkdir -pv "$1" && cd "$1" || {
|
if ! mkdir -pv "$1"; then
|
||||||
printf "Failed create and/or change directory.\n"
|
disp E "Failed to create directory \"$1\"."
|
||||||
return 1
|
return 1
|
||||||
}
|
fi
|
||||||
|
if ! cd "$1"; then
|
||||||
|
disp E "Failed to change to directory \"$1\"."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
export -f mcd
|
export -f mcd
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -241,6 +246,7 @@ rmspc()
|
|||||||
local PARSED
|
local PARSED
|
||||||
|
|
||||||
PARSED=$(getopt -o hr:c::vs --long help,recursive,subst-char::,verbose,shell -n 'rmspc' -- "$@")
|
PARSED=$(getopt -o hr:c::vs --long help,recursive,subst-char::,verbose,shell -n 'rmspc' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"rmspc --help\" to display usage."
|
disp E "Invalid options, use \"rmspc --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -359,7 +365,7 @@ file_stats()
|
|||||||
# Short: H, d, m, M, c, t, a, x:, X:
|
# Short: H, d, m, M, c, t, a, x:, X:
|
||||||
# Long: human, details, average, median, count, total, all, ext:, ext-list:, min:, max:, help
|
# 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' -- "$@")
|
PARSED=$(getopt -o HdmMctax:X:h --long human,details,average,median,count,total,all,ext:,ext-list:,min:,max:,help -n 'file_stats' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"file_stats --help\" to display usage."
|
disp E "Invalid options, use \"file_stats --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -441,7 +447,6 @@ file_stats()
|
|||||||
return 1
|
return 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
shift
|
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ -n "$1" ]] && path="$1"
|
[[ -n "$1" ]] && path="$1"
|
||||||
@@ -578,6 +583,7 @@ findbig()
|
|||||||
|
|
||||||
local PARSED
|
local PARSED
|
||||||
PARSED=$(getopt -o hdl:x --long help,details,limit:,one-fs -n 'findbig' -- "$@")
|
PARSED=$(getopt -o hdl:x --long help,details,limit:,one-fs -n 'findbig' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"findbig --help\" to display usage."
|
disp E "Invalid options, use \"findbig --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -660,6 +666,7 @@ findzero()
|
|||||||
local PARSED
|
local PARSED
|
||||||
# o: options, long: long equivalents
|
# o: options, long: long equivalents
|
||||||
PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'findzero' -- "$@")
|
PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'findzero' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"findzero --help\" to display usage."
|
disp E "Invalid options, use \"findzero --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -733,6 +740,7 @@ finddead()
|
|||||||
|
|
||||||
local PARSED
|
local PARSED
|
||||||
PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'finddead' -- "$@")
|
PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'finddead' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"finddead --help\" to display usage."
|
disp E "Invalid options, use \"finddead --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ busy()
|
|||||||
# Short: h, p:, d:
|
# Short: h, p:, d:
|
||||||
# Long: help, pattern:, delay:
|
# Long: help, pattern:, delay:
|
||||||
PARSED=$(getopt -o hp:d: --long help,pattern:,delay: -n 'busy' -- "$@")
|
PARSED=$(getopt -o hp:d: --long help,pattern:,delay: -n 'busy' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"busy --help\" to display usage."
|
disp E "Invalid options, use \"busy --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -89,7 +90,8 @@ busy()
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Convert milliseconds to seconds for 'sleep'
|
# Convert milliseconds to seconds for 'sleep'
|
||||||
local delay_s=$(awk "BEGIN{
|
local delay_s
|
||||||
|
delay_s=$(awk "BEGIN{
|
||||||
printf \"%.3f\", $delay_ms / 1000 }")
|
printf \"%.3f\", $delay_ms / 1000 }")
|
||||||
|
|
||||||
# Monitor /dev/urandom
|
# Monitor /dev/urandom
|
||||||
|
|||||||
@@ -39,45 +39,48 @@
|
|||||||
# Usage: help
|
# Usage: help
|
||||||
help()
|
help()
|
||||||
{
|
{
|
||||||
|
# shellcheck disable=SC2154 # color code in disp.sh
|
||||||
|
# shellcheck disable=SC2059 # printf format is a color variable
|
||||||
printf "${BIWhite}Welcome to your profile! Here is a list of available commands:${DEFAULTCOL}\n\n"
|
printf "${BIWhite}Welcome to your profile! Here is a list of available commands:${DEFAULTCOL}\n\n"
|
||||||
|
printf "busy\t\tMonitor /dev/urandom for a hex pattern — look busy\n"
|
||||||
printf "check_updates\tCheck for new versions of profile\n"
|
printf "check_updates\tCheck for new versions of profile\n"
|
||||||
printf "clean\t\tErase backup files\n"
|
printf "clean\t\tErase backup files in given directories, optionally recursive\n"
|
||||||
printf "disp\t\tDisplay formatted info/warning/error/debug messages\n"
|
printf "disp\t\tDisplay formatted info/warning/error/debug messages\n"
|
||||||
printf "dwl\t\tDownload a URL to a local file\n"
|
printf "dwl\t\tDownload a URL using curl, wget, or fetch transparently\n"
|
||||||
printf "expandlist\tExpand and quote item lists\n"
|
printf "expandlist\tExpand glob expressions into a quoted, separated list\n"
|
||||||
printf "file_stats\tDisplay file size statistics for a path\n"
|
printf "file_stats\tDisplay file size statistics for a path\n"
|
||||||
printf "findbig\t\tFind biggest files in the given (or current) directory\n"
|
printf "findbig\t\tFind the biggest files in the given or current directory\n"
|
||||||
printf "finddead\tFind dead symbolic links in the given (or current) directory\n"
|
printf "finddead\tFind dead symbolic links in the given or current directory\n"
|
||||||
printf "findzero\tFind empty files in the given (or current) directory\n"
|
printf "findzero\tFind empty files in the given or current directory\n"
|
||||||
printf "genpwd\t\tGenerate secure passwords\n"
|
printf "genpwd\t\tGenerate one or more random secure passwords with configurable constraints\n"
|
||||||
printf "gpid\t\tGive the list of PIDs for the given process name\n"
|
printf "gpid\t\tGive the list of PIDs matching the given process name(s)\n"
|
||||||
printf "isipv4\t\tTell if the given IPv4 is valid\n"
|
printf "isipv4\t\tTell if the given parameter is a valid IPv4 address\n"
|
||||||
printf "isipv6\t\tTell if the given IPv6 is valid\n"
|
printf "isipv6\t\tTell if the given parameter is a valid IPv6 address\n"
|
||||||
printf "ku\t\tKill process owned by users in parameter\n"
|
printf "ku\t\tKill all processes owned by the given user name or ID\n"
|
||||||
printf "matrix\t\tDisplay matrix-style digital rain\n"
|
printf "matrix\t\tConsole screensaver with Matrix-style digital rain (binary, kana, ascii charset)\n"
|
||||||
printf "mcd\t\tCreate a directory and go inside\n"
|
printf "mcd\t\tCreate a directory and immediately move into it\n"
|
||||||
printf "meteo\t\tDisplay current weather forecast for the configured city\n"
|
printf "meteo\t\tDisplay weather forecast for the configured or given city\n"
|
||||||
printf "myextip\tDisplay current external/public IP\n"
|
printf "myextip\t\tGet information about your public IP address\n"
|
||||||
printf "pkgs\t\tSearch for the given package in installed ones\n"
|
printf "pkgs\t\tSearch for a pattern in installed package names (dpkg/rpm, supports -i)\n"
|
||||||
printf "ppg\t\tDisplay process matching the given parameter\n"
|
printf "ppg\t\tLook for the given pattern in running processes\n"
|
||||||
printf "ppn\t\tDisplay process matching the exact process name given in parameter\n"
|
printf "ppn\t\tList processes matching an exact command name\n"
|
||||||
printf "ppu\t\tDisplay processes owned by the given user\n"
|
printf "ppu\t\tList processes owned by a specific user\n"
|
||||||
printf "profile_upgrade\tUpgrade profile to the latest version\n"
|
printf "profile_upgrade\tUpgrade profile to the latest version (git pull or archive)\n"
|
||||||
printf "pwdscore\tCalculate password strength score\n"
|
printf "pwdscore\tCalculate the strength score of a given password\n"
|
||||||
printf "rain\t\tLet the rain fall\n"
|
printf "rain\t\tConsole screensaver with falling-rain effect (multiple color themes)\n"
|
||||||
printf "rmhost\t\tRemove host (IP and/or DNS name) from current known_hosts\n"
|
printf "rmhost\t\tRemove host (name and IP) from SSH known_hosts; supports --all-users as root\n"
|
||||||
printf "rmspc\t\tRemove spaces from file and directory names\n"
|
printf "rmspc\t\tReplace spaces in filenames with underscores (or a custom character)\n"
|
||||||
printf "setlocale\tSet console language to the current locale\n"
|
printf "setlocale\tSet console locale to any installed locale\n"
|
||||||
printf " * setc\tSet console language to C\n"
|
printf " * setc\tSet locale to standard C (POSIX)\n"
|
||||||
printf " * setfr\tSet console language to French\n"
|
printf " * set*\tLocale shortcuts generated from SET_LOCALE in profile.conf\n"
|
||||||
printf " * setus\tSet console language to US English\n"
|
printf "settrace\tActivate or deactivate ERR trap to display backtrace on script errors\n"
|
||||||
printf "settrace\tActivate/deactivate call trace for script debugging\n"
|
printf "set_theme\tSwitch the prompt colour theme; no argument lists available themes\n"
|
||||||
printf "showinfo\tShow welcome banner with basic system information\n"
|
printf "showinfo\tDisplay welcome banner and system information (figlet + neofetch/fastfetch)\n"
|
||||||
printf "ssr\t\tDo a root login to the given address\n"
|
printf "ssr\t\tSSH into a server as root, forwarding extra ssh options\n"
|
||||||
printf "taz\t\tCompress smartly the given files or directory\n"
|
printf "taz\t\tCompress files and directories into a chosen archive format\n"
|
||||||
printf "urlencode\tURL-encode the given text\n"
|
printf "urlencode\tURL-encode a string\n"
|
||||||
printf "utaz\t\tUncompress archives in the given (or current) directory\n"
|
printf "utaz\t\tSmartly uncompress archives (zip, tar.gz/bz2/xz/lz, rar, arj, lha, ace, 7z, zst, cpio, cab, deb, rpm)\n"
|
||||||
printf "ver\t\tDisplay version of your copy of profile\n\n"
|
printf "ver\t\tDisplay the installed profile version\n\n"
|
||||||
|
|
||||||
printf "\nPlease use <command> --help to obtain usage details.\n"
|
printf "\nPlease use <command> --help to obtain usage details.\n"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ ver()
|
|||||||
local PARSED
|
local PARSED
|
||||||
|
|
||||||
PARSED=$(getopt -o h --long help -n 'ver' -- "$@")
|
PARSED=$(getopt -o h --long help -n 'ver' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"ver --help\" to display usage."
|
disp E "Invalid options, use \"ver --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -82,6 +83,7 @@ meteo()
|
|||||||
local PARSED
|
local PARSED
|
||||||
|
|
||||||
PARSED=$(getopt -o h --long help -n 'meteo' -- "$@")
|
PARSED=$(getopt -o h --long help -n 'meteo' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"meteo --help\" to display usage."
|
disp E "Invalid options, use \"meteo --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -133,6 +135,7 @@ showinfo()
|
|||||||
local PARSED
|
local PARSED
|
||||||
|
|
||||||
PARSED=$(getopt -o h --long help -n 'showinfo' -- "$@")
|
PARSED=$(getopt -o h --long help -n 'showinfo' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"showinfo --help\" to display usage."
|
disp E "Invalid options, use \"showinfo --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ setlocale()
|
|||||||
{
|
{
|
||||||
local PARSED
|
local PARSED
|
||||||
PARSED=$(getopt -o h --long help -n 'setlocale' -- "$@")
|
PARSED=$(getopt -o h --long help -n 'setlocale' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"setlocale --help\" to display usage."
|
disp E "Invalid options, use \"setlocale --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -70,9 +70,32 @@ dwl()
|
|||||||
# Honour preferred tool from configuration; fall back to auto-detection.
|
# Honour preferred tool from configuration; fall back to auto-detection.
|
||||||
local preferred="${DWL_PREFERRED_TOOL:-}"
|
local preferred="${DWL_PREFERRED_TOOL:-}"
|
||||||
|
|
||||||
_try_curl() { [ -z "$output" ] && curl -sL "$url" || curl -sL -o "$output" "$url"; }
|
_try_curl()
|
||||||
_try_wget() { [ -z "$output" ] && wget -qO- "$url" || wget -q -O "$output" "$url"; }
|
{
|
||||||
_try_fetch() { [ -z "$output" ] && fetch -o - "$url" || fetch -o "$output" "$url"; }
|
if [[ -z "$output" ]]; then
|
||||||
|
curl -sL "$url"
|
||||||
|
else
|
||||||
|
curl -sL -o "$output" "$url"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_try_wget()
|
||||||
|
{
|
||||||
|
if [[ -z "$output" ]]; then
|
||||||
|
wget -qO- "$url"
|
||||||
|
else
|
||||||
|
wget -q -O "$output" "$url"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_try_fetch()
|
||||||
|
{
|
||||||
|
if [[ -z "$output" ]]; then
|
||||||
|
fetch -o - "$url"
|
||||||
|
else
|
||||||
|
fetch -o "$output" "$url"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
if [[ -n "$preferred" ]]; then
|
if [[ -n "$preferred" ]]; then
|
||||||
command -v "$preferred" >/dev/null 2>&1 || {
|
command -v "$preferred" >/dev/null 2>&1 || {
|
||||||
|
|||||||
@@ -34,15 +34,80 @@
|
|||||||
# * OF SUCH DAMAGE.
|
# * OF SUCH DAMAGE.
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Detect the active package manager of the current distribution.
|
||||||
|
# Detection is based on /etc/os-release (ID / ID_LIKE), then falls back to
|
||||||
|
# checking available binaries in a fixed priority order.
|
||||||
|
# Echoes one of: apt dnf yum zypper pacman apk portage xbps nix
|
||||||
|
# Returns 1 if no known package manager could be identified.
|
||||||
|
_get_pkgmgr()
|
||||||
|
{
|
||||||
|
local distro_id="" distro_like=""
|
||||||
|
if [[ -r /etc/os-release ]]; then
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
distro_id=$( . /etc/os-release 2>/dev/null; printf '%s' "${ID:-}" )
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
distro_like=$( . /etc/os-release 2>/dev/null; printf '%s' "${ID_LIKE:-}" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Map distro IDs/families to a package manager.
|
||||||
|
# ID_LIKE is space-separated and may list multiple families.
|
||||||
|
local id
|
||||||
|
for id in $distro_id $distro_like; do
|
||||||
|
case "${id,,}" in
|
||||||
|
debian|ubuntu|linuxmint|raspbian|pop|kali|elementary|zorin|neon|parrot)
|
||||||
|
echo "apt"; return 0 ;;
|
||||||
|
fedora)
|
||||||
|
echo "dnf"; return 0 ;;
|
||||||
|
rhel|centos|rocky|almalinux|ol|scientific|amzn)
|
||||||
|
command -v dnf >/dev/null 2>&1 && { echo "dnf"; return 0; }
|
||||||
|
echo "yum"; return 0 ;;
|
||||||
|
opensuse*|sles|sled)
|
||||||
|
echo "zypper"; return 0 ;;
|
||||||
|
arch|manjaro|endeavouros|garuda|artix|cachyos)
|
||||||
|
echo "pacman"; return 0 ;;
|
||||||
|
alpine)
|
||||||
|
echo "apk"; return 0 ;;
|
||||||
|
gentoo)
|
||||||
|
echo "portage"; return 0 ;;
|
||||||
|
void)
|
||||||
|
echo "xbps"; return 0 ;;
|
||||||
|
nixos)
|
||||||
|
echo "nix"; return 0 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Fallback: check for binaries in priority order.
|
||||||
|
local bin
|
||||||
|
for bin in apt-get dnf yum zypper pacman apk emerge xbps-install nix-env; do
|
||||||
|
command -v "$bin" >/dev/null 2>&1 && {
|
||||||
|
case "$bin" in
|
||||||
|
apt-get) echo "apt" ;;
|
||||||
|
emerge) echo "portage" ;;
|
||||||
|
xbps-install) echo "xbps" ;;
|
||||||
|
nix-env) echo "nix" ;;
|
||||||
|
*) echo "$bin" ;;
|
||||||
|
esac
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
export -f _get_pkgmgr
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Look for a package within installed one
|
# Look for a package within installed one
|
||||||
# Usage: dpkgs <string>
|
# Usage: pkgs <string>
|
||||||
pkgs()
|
pkgs()
|
||||||
{
|
{
|
||||||
local ignore_case=${PKGS_DEFAULT_IGNORE_CASE:-0}
|
local ignore_case=${PKGS_DEFAULT_IGNORE_CASE:-0}
|
||||||
|
|
||||||
local PARSED
|
local PARSED
|
||||||
PARSED=$(getopt -o hi --long help,ignore-case -n 'pkgs' -- "$@")
|
PARSED=$(getopt -o hi --long help,ignore-case -n 'pkgs' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"pkgs --help\" to display usage."
|
disp E "Invalid options, use \"pkgs --help\" to display usage."
|
||||||
return 1
|
return 1
|
||||||
@@ -84,13 +149,28 @@ pkgs()
|
|||||||
local grep_opt=""
|
local grep_opt=""
|
||||||
(( ignore_case )) && grep_opt="-i"
|
(( ignore_case )) && grep_opt="-i"
|
||||||
|
|
||||||
command -v dpkg >/dev/null 2>&1 && local cmd="dpkg -l"
|
local pkgmgr
|
||||||
command -v rpm >/dev/null 2>&1 && local cmd="rpm -qa"
|
pkgmgr=$(_get_pkgmgr) || {
|
||||||
if [[ -z $cmd ]]; then
|
disp E "No usable package manager could be detected on this system."
|
||||||
disp E "No usable package manager seems unavialable."
|
|
||||||
return 2
|
return 2
|
||||||
fi
|
}
|
||||||
$cmd | grep $grep_opt $pkg
|
|
||||||
|
local -a list_cmd
|
||||||
|
case "$pkgmgr" in
|
||||||
|
apt) list_cmd=(dpkg-query -l) ;;
|
||||||
|
dnf|yum|zypper) list_cmd=(rpm -qa) ;;
|
||||||
|
pacman) list_cmd=(pacman -Q) ;;
|
||||||
|
apk) list_cmd=(apk list --installed) ;;
|
||||||
|
portage) list_cmd=(qlist -I) ;;
|
||||||
|
xbps) list_cmd=(xbps-query -l) ;;
|
||||||
|
nix) list_cmd=(nix-env -q) ;;
|
||||||
|
*)
|
||||||
|
disp E "Package manager '$pkgmgr' is not supported by pkgs."
|
||||||
|
return 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
"${list_cmd[@]}" | grep ${grep_opt:+"$grep_opt"} "$pkg"
|
||||||
}
|
}
|
||||||
export -f pkgs
|
export -f pkgs
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ ppn()
|
|||||||
# -e: select all processes
|
# -e: select all processes
|
||||||
# -o: specify custom output columns (PID and Command name)
|
# -o: specify custom output columns (PID and Command name)
|
||||||
# grep -w: ensures exact word matching so 'bash' doesn't match 'dbash'
|
# grep -w: ensures exact word matching so 'bash' doesn't match 'dbash'
|
||||||
|
# shellcheck disable=SC2009 # pgrep do not offer the -w switch
|
||||||
ps -eo pid,comm | grep -w "$1"
|
ps -eo pid,comm | grep -w "$1"
|
||||||
}
|
}
|
||||||
export -f ppn
|
export -f ppn
|
||||||
@@ -200,8 +201,7 @@ ku()
|
|||||||
disp E "Usage: ku <username1 [username2 ...]>"
|
disp E "Usage: ku <username1 [username2 ...]>"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
local users="$@"
|
for u in "$@"; do
|
||||||
for u in $users; do
|
|
||||||
if ! id "$u" >/dev/null 2>&1; then
|
if ! id "$u" >/dev/null 2>&1; then
|
||||||
disp E "User '$u' does not exist."
|
disp E "User '$u' does not exist."
|
||||||
return 1
|
return 1
|
||||||
@@ -227,7 +227,7 @@ kt()
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
if [[ -z "$1" ]]; then
|
if [[ -z "$1" ]]; then
|
||||||
disp E "Usage: ppg <string>"
|
disp E "Usage: kt <pid>"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -238,7 +238,8 @@ kt()
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local children_pids=$(pgrep -P "$parent_pid")
|
local children_pids
|
||||||
|
children_pids=$(pgrep -P "$parent_pid")
|
||||||
|
|
||||||
for pid in $children_pids; do
|
for pid in $children_pids; do
|
||||||
kt "$pid" "$@" || break
|
kt "$pid" "$@" || break
|
||||||
|
|||||||
@@ -140,9 +140,14 @@ load_theme()
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Strip surrounding quotes
|
# Strip surrounding quotes (handles inline trailing comments like KEY="val" # note)
|
||||||
_lth_value="${_lth_value#\"}" ; _lth_value="${_lth_value%\"}"
|
if [[ "$_lth_value" == '"'* ]]; then
|
||||||
_lth_value="${_lth_value#\'}" ; _lth_value="${_lth_value%\'}"
|
_lth_value="${_lth_value#\"}"
|
||||||
|
_lth_value="${_lth_value%%\"*}"
|
||||||
|
elif [[ "$_lth_value" == "'"* ]]; then
|
||||||
|
_lth_value="${_lth_value#\'}"
|
||||||
|
_lth_value="${_lth_value%%\'*}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ "$_lth_value" =~ $_lth_ref_re ]]; then
|
if [[ "$_lth_value" =~ $_lth_ref_re ]]; then
|
||||||
# Safe colour variable reference — resolve via indirection
|
# Safe colour variable reference — resolve via indirection
|
||||||
@@ -159,6 +164,67 @@ load_theme()
|
|||||||
fi
|
fi
|
||||||
done < "$theme_file"
|
done < "$theme_file"
|
||||||
}
|
}
|
||||||
|
# Not exported, it remains private
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Dynamically switch the prompt theme for the current shell session.
|
||||||
|
# Calls load_theme to apply the new colour values immediately, then updates
|
||||||
|
# PROMPT_THEME so subshells and the set_prompt fallback chain reflect the
|
||||||
|
# change. PROMPT_THEME_DIR is honoured when set.
|
||||||
|
# Usage: set_theme [theme_name_or_path]
|
||||||
|
# With no argument (or -l / --list), lists available .theme files.
|
||||||
|
set_theme()
|
||||||
|
{
|
||||||
|
local theme_dir="${PROMPT_THEME_DIR:-${MYPATH}/profile.d/themes}"
|
||||||
|
|
||||||
|
# -- help mode -----------------------------------------------------------
|
||||||
|
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
||||||
|
printf "set_theme: Switch the prompt colour theme for the current shell session.\n\n"
|
||||||
|
printf "Usage: set_theme [options] [theme]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf " -h, --help Display this help screen\n"
|
||||||
|
printf " -l, --list List available themes (default when no argument is given)\n\n"
|
||||||
|
printf "Arguments:\n"
|
||||||
|
printf " theme Bare theme name (e.g. 'dark') or an explicit path to a .theme file.\n"
|
||||||
|
printf " Themes are searched in: %s\n" "$theme_dir"
|
||||||
|
printf " Override with PROMPT_THEME_DIR in profile.conf [prompt].\n\n"
|
||||||
|
printf "Examples:\n"
|
||||||
|
printf " set_theme — list available themes\n"
|
||||||
|
printf " set_theme dark — apply the dark theme\n"
|
||||||
|
printf " set_theme ~/my.theme — apply a theme by path\n"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -- list mode -----------------------------------------------------------
|
||||||
|
if [[ $# -eq 0 || "$1" == "-l" || "$1" == "--list" ]]; then
|
||||||
|
printf "Available themes in %s:\n" "$theme_dir"
|
||||||
|
local f name
|
||||||
|
for f in "$theme_dir"/*.theme; do
|
||||||
|
[[ -f "$f" ]] || continue
|
||||||
|
name="${f##*/}"
|
||||||
|
name="${name%.theme}"
|
||||||
|
if [[ "$name" == "${PROMPT_THEME:-}" ]]; then
|
||||||
|
printf " * %s (active)\n" "$name"
|
||||||
|
else
|
||||||
|
printf " %s\n" "$name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -- apply mode ----------------------------------------------------------
|
||||||
|
local theme_name="$1"
|
||||||
|
|
||||||
|
# Reset colours to defaults before loading the new theme
|
||||||
|
set_colors
|
||||||
|
load_theme "$theme_name" || return 1
|
||||||
|
|
||||||
|
export PROMPT_THEME="$theme_name"
|
||||||
|
disp I "Prompt theme set to $theme_name."
|
||||||
|
}
|
||||||
|
export -f set_theme
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@@ -186,7 +252,7 @@ function timer_start
|
|||||||
# into a human-readable string with appropriate units (us, ms, s, m, h
|
# 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))
|
||||||
local us=$((delta_us % 1000))
|
local us=$((delta_us % 1000))
|
||||||
local ms=$(((delta_us / 1000) % 1000))
|
local ms=$(((delta_us / 1000) % 1000))
|
||||||
local s=$(((delta_us / 1000000) % 60))
|
local s=$(((delta_us / 1000000) % 60))
|
||||||
@@ -225,43 +291,48 @@ set_prompt()
|
|||||||
|
|
||||||
# Resolve theme/config colours with hardcoded fallbacks
|
# Resolve theme/config colours with hardcoded fallbacks
|
||||||
local _time_fg="${PROMPT_COLOR_TIME_FG:-$Blue}"
|
local _time_fg="${PROMPT_COLOR_TIME_FG:-$Blue}"
|
||||||
local _time_bg="${PROMPT_COLOR_TIME_BG:-$On_IBlack}"
|
local _time_bg="${PROMPT_COLOR_TIME_BG:-$On_White}"
|
||||||
local _bar_bg="${PROMPT_COLOR_BAR_BG:-$On_Blue}"
|
local _bar_bg="${PROMPT_COLOR_BAR_BG:-$On_Blue}"
|
||||||
local _ok_fg="${PROMPT_COLOR_OK_FG:-$White}"
|
local _ok_fg="${PROMPT_COLOR_OK_FG:-$BWhite}"
|
||||||
local _ok_mark="${PROMPT_COLOR_OK_MARK:-$Green}"
|
local _ok_mark="${PROMPT_COLOR_OK_MARK:-$BGreen}"
|
||||||
local _err_bg="${PROMPT_COLOR_ERR_BG:-$On_Red}"
|
local _err_bg="${PROMPT_COLOR_ERR_BG:-$On_Red}"
|
||||||
local _err_fg="${PROMPT_COLOR_ERR_FG:-$White}"
|
local _err_fg="${PROMPT_COLOR_ERR_FG:-$White}"
|
||||||
local _err_mark="${PROMPT_COLOR_ERR_MARK:-$BYellow}"
|
local _err_mark="${PROMPT_COLOR_ERR_MARK:-$BYellow}"
|
||||||
local _root_fg="${PROMPT_COLOR_ROOT_FG:-$Red}"
|
local _root_fg="${PROMPT_COLOR_ROOT_FG:-$Red}"
|
||||||
local _user_fg="${PROMPT_COLOR_USER_FG:-$Green}"
|
local _user_fg="${PROMPT_COLOR_USER_FG:-$BGreen}"
|
||||||
local _dir_fg="${PROMPT_COLOR_DIR_FG:-$ICyan}"
|
local _dir_fg="${PROMPT_COLOR_DIR_FG:-$ICyan}"
|
||||||
|
|
||||||
# Begin with time
|
# Begin with time (cursor-save is non-printing; all ANSI sequences wrapped
|
||||||
PS1="\[\e[s${_time_fg}${_time_bg} [ \t ] ${_bar_bg}"
|
# in \[...\] so bash does not count them toward the visible line width).
|
||||||
|
# Every fg colour is combined with its section bg in the same \[...\] block
|
||||||
|
# so that even "reset" colours (0;Xm) cannot strip the background.
|
||||||
|
PS1="\[\e[s\]\[${_time_fg}${_time_bg}\] [ \t ] \[${_bar_bg}\]"
|
||||||
|
|
||||||
# Add exit status of the last command.
|
# Add exit status of the last command.
|
||||||
# If it was successful, print a green check mark. Otherwise, print a red X.
|
# If it was successful, print a green check mark. Otherwise, print a red X.
|
||||||
if [[ $Last_Command == 0 ]]; then
|
if [[ $Last_Command == 0 ]]; then
|
||||||
PS1+="${_ok_fg}${_bar_bg} [ \$Last_Command "
|
PS1+="\[${_ok_fg}${_bar_bg}\] [ $Last_Command "
|
||||||
PS1+="${_ok_mark}${Checkmark} "
|
PS1+="\[${_ok_mark}${_bar_bg}\]${Checkmark} "
|
||||||
|
# Add the elapsed time, then close the status section and return to bar bg.
|
||||||
|
timer_stop
|
||||||
|
PS1+="($timer_show)\[${_ok_fg}${_bar_bg}\] ] "
|
||||||
else
|
else
|
||||||
PS1+="${_err_fg}${_err_bg} [ \$Last_Command "
|
PS1+="\[${_err_fg}${_err_bg}\] [ $Last_Command "
|
||||||
PS1+="${_err_mark}${FancyX} "
|
PS1+="\[${_err_mark}${_err_bg}\]${FancyX} "
|
||||||
|
timer_stop
|
||||||
|
PS1+="($timer_show)\[${_err_fg}${_err_bg}\] ] "
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Add the elapsed time
|
|
||||||
timer_stop
|
|
||||||
PS1+="($timer_show)${_ok_fg} ] ${_bar_bg} "
|
|
||||||
|
|
||||||
# If root, print the host in root colour. Otherwise use user colour.
|
# If root, print the host in root colour. Otherwise use user colour.
|
||||||
if [[ $EUID -eq 0 ]]; then
|
if [[ $EUID -eq 0 ]]; then
|
||||||
PS1+="${_root_fg}\\u${_user_fg}@\\h"
|
PS1+="\[${_root_fg}${_bar_bg}\] \\u\[${_user_fg}${_bar_bg}\]@\\h"
|
||||||
else
|
else
|
||||||
PS1+="${_user_fg}\\u@\\h"
|
PS1+="\[${_user_fg}${_bar_bg}\] \\u@\\h"
|
||||||
fi
|
fi
|
||||||
PS1+="\e[K\e[u$DEFAULTCOL\n"
|
PS1+="\[\e[K\e[u\]\[$RESETCOL\]\n"
|
||||||
# Print the working directory and prompt marker, then reset colour.
|
# Print the working directory and prompt marker, then reset colour.
|
||||||
PS1+="${_dir_fg}\\w \\\$$DEFAULTCOL "
|
PS1+="\[${_dir_fg}\]\\w \\\$\[$RESETCOL\] "
|
||||||
}
|
}
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ genpwd()
|
|||||||
PARSED=$(getopt -o hsnule:L:o: --long \
|
PARSED=$(getopt -o hsnule:L:o: --long \
|
||||||
help,nosymbols,nonumbers,noup,nolow,extracars:,length:,occurences:,occurrences: \
|
help,nosymbols,nonumbers,noup,nolow,extracars:,length:,occurences:,occurrences: \
|
||||||
-n 'genpwd' -- "$@")
|
-n 'genpwd' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then return 1; fi
|
if [[ $? -ne 0 ]]; then return 1; fi
|
||||||
eval set -- "$PARSED"
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ rmhost()
|
|||||||
local -a known_hosts_files=()
|
local -a known_hosts_files=()
|
||||||
|
|
||||||
PARSED=$(getopt -o ha --long help,all-users -n 'rmhost' -- "$@")
|
PARSED=$(getopt -o ha --long help,all-users -n 'rmhost' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then return 1; fi
|
if [[ $? -ne 0 ]]; then return 1; fi
|
||||||
eval set -- "$PARSED"
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
@@ -194,6 +195,7 @@ ssr()
|
|||||||
ssh_default_opts=(-Y)
|
ssh_default_opts=(-Y)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# shellcheck disable=SC2029
|
||||||
ssh "${ssh_default_opts[@]}" root@"$srv" "$@"
|
ssh "${ssh_default_opts[@]}" root@"$srv" "$@"
|
||||||
}
|
}
|
||||||
export -f ssr
|
export -f ssr
|
||||||
|
|||||||
8
profile.d/themes/abyss.theme
Executable file → Normal file
8
profile.d/themes/abyss.theme
Executable file → Normal file
@@ -27,14 +27,14 @@ Green="\e[0;96m" # teal (ICyan — abyss string colour)
|
|||||||
Yellow="\e[0;93m" # bright gold (IYellow — abyss constant colour)
|
Yellow="\e[0;93m" # bright gold (IYellow — abyss constant colour)
|
||||||
|
|
||||||
PROMPT_COLOR_TIME_FG="$ICyan" # electric teal clock
|
PROMPT_COLOR_TIME_FG="$ICyan" # electric teal clock
|
||||||
PROMPT_COLOR_TIME_BG="$On_Black" # deep black background
|
PROMPT_COLOR_TIME_BG="\e[48;2;0;60;70m" # very dark cyan bg for time
|
||||||
PROMPT_COLOR_BAR_BG="$On_Blue" # deep blue bar
|
PROMPT_COLOR_BAR_BG="\e[48;2;0;30;70m" # deep navy bar (24-bit)
|
||||||
|
|
||||||
PROMPT_COLOR_OK_FG="$ICyan" # teal on success
|
PROMPT_COLOR_OK_FG="$ICyan" # teal on success
|
||||||
PROMPT_COLOR_OK_MARK="$IGreen" # bright teal-green checkmark
|
PROMPT_COLOR_OK_MARK="$IGreen" # bright teal-green checkmark
|
||||||
|
|
||||||
PROMPT_COLOR_ERR_BG="$On_Red" # red background on failure
|
PROMPT_COLOR_ERR_BG="\e[48;2;180;20;20m" # vivid crimson background (24-bit)
|
||||||
PROMPT_COLOR_ERR_FG="$IWhite" # bright white text
|
PROMPT_COLOR_ERR_FG="\e[1;97m" # bold bright white — maximum contrast
|
||||||
PROMPT_COLOR_ERR_MARK="$IYellow" # golden X
|
PROMPT_COLOR_ERR_MARK="$IYellow" # golden X
|
||||||
|
|
||||||
PROMPT_COLOR_ROOT_FG="$IRed" # red for root
|
PROMPT_COLOR_ROOT_FG="$IRed" # red for root
|
||||||
|
|||||||
4
profile.d/themes/adwaita.theme
Executable file → Normal file
4
profile.d/themes/adwaita.theme
Executable file → Normal file
@@ -34,9 +34,9 @@ PROMPT_COLOR_OK_FG="$White" # clean white on success
|
|||||||
PROMPT_COLOR_OK_MARK="$Green" # Adwaita green checkmark
|
PROMPT_COLOR_OK_MARK="$Green" # Adwaita green checkmark
|
||||||
|
|
||||||
PROMPT_COLOR_ERR_BG="$On_Red" # Adwaita red on failure
|
PROMPT_COLOR_ERR_BG="$On_Red" # Adwaita red on failure
|
||||||
PROMPT_COLOR_ERR_FG="$White" # white text
|
PROMPT_COLOR_ERR_FG="$BIWhite" # bold bright white for maximum legibility
|
||||||
PROMPT_COLOR_ERR_MARK="$Yellow" # yellow X (warning intent)
|
PROMPT_COLOR_ERR_MARK="$Yellow" # yellow X (warning intent)
|
||||||
|
|
||||||
PROMPT_COLOR_ROOT_FG="$Red" # Adwaita red for root
|
PROMPT_COLOR_ROOT_FG="$Red" # Adwaita red for root
|
||||||
PROMPT_COLOR_USER_FG="$IBlue" # Adwaita blue for user
|
PROMPT_COLOR_USER_FG="$BBlue" # darker bold blue — readable on blue bar
|
||||||
PROMPT_COLOR_DIR_FG="$IGreen" # Adwaita green for path
|
PROMPT_COLOR_DIR_FG="$IGreen" # Adwaita green for path
|
||||||
|
|||||||
4
profile.d/themes/dark.theme
Executable file → Normal file
4
profile.d/themes/dark.theme
Executable file → Normal file
@@ -17,8 +17,8 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
PROMPT_COLOR_TIME_FG="$ICyan" # Clock text
|
PROMPT_COLOR_TIME_FG="$ICyan" # Clock text
|
||||||
PROMPT_COLOR_TIME_BG="$On_Black" # Clock background (black)
|
PROMPT_COLOR_TIME_BG="$On_IBlack" # Clock background (black)
|
||||||
PROMPT_COLOR_BAR_BG="$On_IBlack" # Main bar background (dark grey)
|
PROMPT_COLOR_BAR_BG="$On_Black" # Main bar background (dark grey)
|
||||||
|
|
||||||
PROMPT_COLOR_OK_FG="$IGreen" # Exit-code text on success
|
PROMPT_COLOR_OK_FG="$IGreen" # Exit-code text on success
|
||||||
PROMPT_COLOR_OK_MARK="$BGreen" # Checkmark colour on success
|
PROMPT_COLOR_OK_MARK="$BGreen" # Checkmark colour on success
|
||||||
|
|||||||
2
profile.d/themes/default.theme
Executable file → Normal file
2
profile.d/themes/default.theme
Executable file → Normal file
@@ -17,7 +17,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
PROMPT_COLOR_TIME_FG="$Blue" # Clock text
|
PROMPT_COLOR_TIME_FG="$Blue" # Clock text
|
||||||
PROMPT_COLOR_TIME_BG="$On_IBlack" # Clock background (dark grey)
|
PROMPT_COLOR_TIME_BG="$On_White" # Clock background (dark grey)
|
||||||
PROMPT_COLOR_BAR_BG="$On_Blue" # Main bar background
|
PROMPT_COLOR_BAR_BG="$On_Blue" # Main bar background
|
||||||
|
|
||||||
PROMPT_COLOR_OK_FG="$White" # Exit-code text on success
|
PROMPT_COLOR_OK_FG="$White" # Exit-code text on success
|
||||||
|
|||||||
2
profile.d/themes/light.theme
Executable file → Normal file
2
profile.d/themes/light.theme
Executable file → Normal file
@@ -19,7 +19,7 @@
|
|||||||
# shift to their dark/regular equivalents for contrast on a light terminal.
|
# shift to their dark/regular equivalents for contrast on a light terminal.
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
PROMPT_COLOR_TIME_FG="$Blue" # Clock text (ICyan → Blue, darker for light bg)
|
PROMPT_COLOR_TIME_FG="$BBlack" # Clock text (bold black — forces true black on terminals that render Black as dark grey)
|
||||||
PROMPT_COLOR_TIME_BG="$On_IWhite" # Clock background (On_Black → On_IWhite)
|
PROMPT_COLOR_TIME_BG="$On_IWhite" # Clock background (On_Black → On_IWhite)
|
||||||
PROMPT_COLOR_BAR_BG="$On_White" # Main bar background (On_IBlack → On_White)
|
PROMPT_COLOR_BAR_BG="$On_White" # Main bar background (On_IBlack → On_White)
|
||||||
|
|
||||||
|
|||||||
0
profile.d/themes/monochrome.theme
Executable file → Normal file
0
profile.d/themes/monochrome.theme
Executable file → Normal file
0
profile.d/themes/monokai.theme
Executable file → Normal file
0
profile.d/themes/monokai.theme
Executable file → Normal file
6
profile.d/themes/plasma.theme
Executable file → Normal file
6
profile.d/themes/plasma.theme
Executable file → Normal file
@@ -26,9 +26,9 @@ Blue="\e[0;94m" # electric blue (IBlue)
|
|||||||
Purple="\e[0;95m" # vivid magenta (IPurple — Plasma's signature colour)
|
Purple="\e[0;95m" # vivid magenta (IPurple — Plasma's signature colour)
|
||||||
Cyan="\e[0;96m" # electric cyan (ICyan)
|
Cyan="\e[0;96m" # electric cyan (ICyan)
|
||||||
|
|
||||||
PROMPT_COLOR_TIME_FG="$IPurple" # vivid purple clock text
|
PROMPT_COLOR_TIME_FG="$BIPurple" # vivid purple clock text
|
||||||
PROMPT_COLOR_TIME_BG="$On_IBlack" # dark grey background
|
PROMPT_COLOR_TIME_BG="\e[48;2;50;50;55m" # deep charcoal (darker than On_IBlack)
|
||||||
PROMPT_COLOR_BAR_BG="$On_Purple" # bright magenta bar
|
PROMPT_COLOR_BAR_BG="\e[48;2;75;0;130m" # deep indigo-purple (24-bit) — darker than On_Purple
|
||||||
|
|
||||||
PROMPT_COLOR_OK_FG="$ICyan" # electric cyan on success
|
PROMPT_COLOR_OK_FG="$ICyan" # electric cyan on success
|
||||||
PROMPT_COLOR_OK_MARK="$IGreen" # green checkmark
|
PROMPT_COLOR_OK_MARK="$IGreen" # green checkmark
|
||||||
|
|||||||
0
profile.d/themes/solarized-light.theme
Executable file → Normal file
0
profile.d/themes/solarized-light.theme
Executable file → Normal file
8
profile.d/themes/solarized.theme
Executable file → Normal file
8
profile.d/themes/solarized.theme
Executable file → Normal file
@@ -108,14 +108,14 @@ RESETCOL="\e[0m"
|
|||||||
|
|
||||||
PROMPT_COLOR_TIME_FG="\e[38;2;181;137;0m" # Yellow — primary accent
|
PROMPT_COLOR_TIME_FG="\e[38;2;181;137;0m" # Yellow — primary accent
|
||||||
PROMPT_COLOR_TIME_BG="\e[48;2;0;43;54m" # Base03 — darkest background
|
PROMPT_COLOR_TIME_BG="\e[48;2;0;43;54m" # Base03 — darkest background
|
||||||
PROMPT_COLOR_BAR_BG="\e[48;2;7;54;66m" # Base02 — bar background
|
PROMPT_COLOR_BAR_BG="\e[48;2;88;110;117m" # Base01 — slightly brighter bar (was Base02)
|
||||||
|
|
||||||
PROMPT_COLOR_OK_FG="\e[38;2;131;148;150m" # Base0 — body text on success
|
PROMPT_COLOR_OK_FG="\e[38;2;131;148;150m" # Base0 — body text on success
|
||||||
PROMPT_COLOR_OK_MARK="\e[38;2;133;153;0m" # Green — checkmark
|
PROMPT_COLOR_OK_MARK="\e[38;2;133;153;0m" # Green — checkmark
|
||||||
|
|
||||||
PROMPT_COLOR_ERR_BG="\e[48;2;220;50;47m" # Red — error background
|
PROMPT_COLOR_ERR_BG="\e[48;2;180;20;15m" # deeper crimson — more contrast than Solarized Red
|
||||||
PROMPT_COLOR_ERR_FG="\e[38;2;253;246;227m" # Base3 — bright fg on red
|
PROMPT_COLOR_ERR_FG="\e[1;38;2;255;255;255m" # bold pure white — maximum contrast on dark red
|
||||||
PROMPT_COLOR_ERR_MARK="\e[38;2;181;137;0m" # Yellow — X mark on red bg
|
PROMPT_COLOR_ERR_MARK="\e[1;38;2;253;246;227m" # Base3 bold — bright warm mark stands out on crimson
|
||||||
|
|
||||||
PROMPT_COLOR_ROOT_FG="\e[38;2;220;50;47m" # Red — root warning
|
PROMPT_COLOR_ROOT_FG="\e[38;2;220;50;47m" # Red — root warning
|
||||||
PROMPT_COLOR_USER_FG="\e[38;2;42;161;152m" # Cyan — normal user
|
PROMPT_COLOR_USER_FG="\e[38;2;42;161;152m" # Cyan — normal user
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ check_updates()
|
|||||||
local vfile="" lastver=""
|
local vfile="" lastver=""
|
||||||
|
|
||||||
PARSED=$(getopt -o hq --long help,quiet -n 'check_updates' -- "$@")
|
PARSED=$(getopt -o hq --long help,quiet -n 'check_updates' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"check_updates --help\" to display usage."
|
disp E "Invalid options, use \"check_updates --help\" to display usage."
|
||||||
return 2
|
return 2
|
||||||
@@ -128,6 +129,7 @@ profile_upgrade()
|
|||||||
local tmpdir="" archive="" extracted_root=""
|
local tmpdir="" archive="" extracted_root=""
|
||||||
|
|
||||||
PARSED=$(getopt -o hf:t:nFb:g --long help,file:,tmpdir:,dry-run,force,branch:,switch-to-git -n 'profile_upgrade' -- "$@")
|
PARSED=$(getopt -o hf:t:nFb:g --long help,file:,tmpdir:,dry-run,force,branch:,switch-to-git -n 'profile_upgrade' -- "$@")
|
||||||
|
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"profile_upgrade --help\" to display usage."
|
disp E "Invalid options, use \"profile_upgrade --help\" to display usage."
|
||||||
return 2
|
return 2
|
||||||
@@ -215,8 +217,8 @@ profile_upgrade()
|
|||||||
}
|
}
|
||||||
if (( dry_run )); then
|
if (( dry_run )); then
|
||||||
disp I "[dry-run] rm -rf \"$MYPATH\"/.git"
|
disp I "[dry-run] rm -rf \"$MYPATH\"/.git"
|
||||||
disp I "[dry-run] git clone "$BASE_URL" \"$MYPATH\""
|
disp I "[dry-run] git clone $BASE_URL \"$MYPATH\""
|
||||||
[[ -n "$branch" ]] && disp I "[dry-run] git -C \"$MYPATH\" checkout "$branch""
|
[[ -n "$branch" ]] && disp I "[dry-run] git -C \"$MYPATH\" checkout $branch"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
59
profile.sh
59
profile.sh
@@ -45,7 +45,7 @@ fi
|
|||||||
if ((BASH_VERSINFO[0] < 4)) || [[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 3 ]]; then
|
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 "[ Error ] This profile requires Bash 4.3 or higher."
|
||||||
echo "Current version: $BASH_VERSION"
|
echo "Current version: $BASH_VERSION"
|
||||||
return 1 2>/dev/null || exit 1
|
(return 0 2>/dev/null) && return 1 || exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -66,17 +66,17 @@ pathremove()
|
|||||||
export "$pathvar=$newpath"
|
export "$pathvar=$newpath"
|
||||||
}
|
}
|
||||||
|
|
||||||
pathprepend()
|
#pathprepend() # Unused for now, but might be useful in the future
|
||||||
{
|
#{
|
||||||
[[ -z "$1" ]] && return 0
|
# [[ -z "$1" ]] && return 0
|
||||||
local pathvar="${2:-PATH}"
|
# local pathvar="${2:-PATH}"
|
||||||
[[ "$pathvar" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || {
|
# [[ "$pathvar" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || {
|
||||||
printf "pathprepend: unsafe variable name '%s'\n" "$pathvar" >&2
|
# printf "pathprepend: unsafe variable name '%s'\n" "$pathvar" >&2
|
||||||
return 1
|
# return 1
|
||||||
}
|
# }
|
||||||
pathremove "$1" "$pathvar"
|
# pathremove "$1" "$pathvar"
|
||||||
export "$pathvar=$1${!pathvar:+:${!pathvar}}"
|
# export "$pathvar=$1${!pathvar:+:${!pathvar}}"
|
||||||
}
|
#}
|
||||||
|
|
||||||
pathappend()
|
pathappend()
|
||||||
{
|
{
|
||||||
@@ -98,7 +98,7 @@ parse_conf()
|
|||||||
{
|
{
|
||||||
local config_file="$1"
|
local config_file="$1"
|
||||||
local current_section=""
|
local current_section=""
|
||||||
local line key value
|
local key value
|
||||||
|
|
||||||
[[ ! -f "$config_file" ]] && return 1
|
[[ ! -f "$config_file" ]] && return 1
|
||||||
|
|
||||||
@@ -140,6 +140,7 @@ parse_conf()
|
|||||||
|
|
||||||
# Use a nameref for safe, eval-free assignment
|
# Use a nameref for safe, eval-free assignment
|
||||||
local -n current_array="CONF_$current_section"
|
local -n current_array="CONF_$current_section"
|
||||||
|
# shellcheck disable=SC2034 # Dynamic var creation
|
||||||
current_array["$key"]="$value"
|
current_array["$key"]="$value"
|
||||||
fi
|
fi
|
||||||
done < "$config_file"
|
done < "$config_file"
|
||||||
@@ -168,6 +169,7 @@ load_alias()
|
|||||||
|
|
||||||
# Only alias if the base command is executable
|
# Only alias if the base command is executable
|
||||||
if command -v "$base_cmd" >/dev/null 2>&1; then
|
if command -v "$base_cmd" >/dev/null 2>&1; then
|
||||||
|
# shellcheck disable=SC2139 # Dynamic alias creation
|
||||||
alias "$key"="$cmd"
|
alias "$key"="$cmd"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -181,7 +183,8 @@ load_conf()
|
|||||||
{
|
{
|
||||||
local section_name="CONF_$1"
|
local section_name="CONF_$1"
|
||||||
|
|
||||||
[[ "$(declare -p "$section_name" 2>/dev/null)" != "declare -A"* ]] && return 1
|
# Missing section is not an error: modules can rely on built-in defaults.
|
||||||
|
[[ "$(declare -p "$section_name" 2>/dev/null)" != "declare -A"* ]] && return 0
|
||||||
|
|
||||||
local -n current_vars="$section_name"
|
local -n current_vars="$section_name"
|
||||||
|
|
||||||
@@ -204,22 +207,24 @@ load_conf()
|
|||||||
# Because we're more likely to be sourced, we use BASH_SOURCE to get the path
|
# Because we're more likely to be sourced, we use BASH_SOURCE to get the path
|
||||||
# of the sourced file instead of $0
|
# of the sourced file instead of $0
|
||||||
if [[ -z "$PROFILE_PATH" ]]; then
|
if [[ -z "$PROFILE_PATH" ]]; then
|
||||||
export MYPATH=$(dirname "$(realpath -s "${BASH_SOURCE[0]}")")
|
MYPATH=$(dirname "$(realpath -s "${BASH_SOURCE[0]}")")
|
||||||
else
|
else
|
||||||
export MYPATH="$PROFILE_PATH"
|
MYPATH="$PROFILE_PATH"
|
||||||
fi
|
fi
|
||||||
|
export MYPATH
|
||||||
if [[ ! -e "$MYPATH/profile.sh" ]]; then
|
if [[ ! -e "$MYPATH/profile.sh" ]]; then
|
||||||
echo "[ Warning ] Path detection failed, trying to use pwd..."
|
echo "[ Warning ] Path detection failed, trying to use pwd..."
|
||||||
MYPATH=$(pwd)
|
MYPATH=$(pwd)
|
||||||
if [[ ! -e "$MYPATH/profile.sh" ]]; then
|
if [[ ! -e "$MYPATH/profile.sh" ]]; then
|
||||||
echo "[ Error ] Impossible to determine installation path, pretty much nothing will work."
|
echo "[ Error ] Unable to determine installation path, pretty much nothing will work."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -s "$MYPATH/version" ]]; then
|
if [[ ! -s "$MYPATH/version" ]]; then
|
||||||
echo "[ Warning ] Impossible to determine running version of profile, your installation might be broken."
|
echo "[ Warning ] Unable to determine running profile version; your installation might be broken."
|
||||||
fi
|
fi
|
||||||
export PROFVERSION=$(cat "$MYPATH"/version)
|
PROFVERSION=$(cat "$MYPATH"/version)
|
||||||
|
export PROFVERSION
|
||||||
|
|
||||||
# Build PATH environment variable
|
# Build PATH environment variable
|
||||||
if [[ $EUID -eq 0 ]]; then
|
if [[ $EUID -eq 0 ]]; then
|
||||||
@@ -258,11 +263,21 @@ if [[ $INTERACTIVE ]]; then
|
|||||||
trap 'timer_start' DEBUG
|
trap 'timer_start' DEBUG
|
||||||
PROMPT_COMMAND='set_prompt'
|
PROMPT_COMMAND='set_prompt'
|
||||||
|
|
||||||
# Set default language
|
# Set default language from DEFAULT_LANG config key (set in [general]).
|
||||||
setfr
|
# The value must match one of the alias names defined in SET_LOCALE so that
|
||||||
|
# the corresponding set<alias> function exists after build_locale_shortcuts.
|
||||||
|
if [[ -n "${DEFAULT_LANG:-}" ]]; then
|
||||||
|
_lang_fn="set${DEFAULT_LANG}"
|
||||||
|
if declare -F "$_lang_fn" >/dev/null 2>&1; then
|
||||||
|
"$_lang_fn"
|
||||||
|
else
|
||||||
|
disp W "DEFAULT_LANG '$DEFAULT_LANG' has no matching locale shortcut (check SET_LOCALE in profile.conf)."
|
||||||
|
fi
|
||||||
|
unset _lang_fn
|
||||||
|
fi
|
||||||
showinfo && printf "\n"
|
showinfo && printf "\n"
|
||||||
check_updates -q
|
check_updates -q
|
||||||
disp I "Profile version $PROFVERSION chargé..."
|
disp I "Profile version $PROFVERSION loaded..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
|
|||||||
Reference in New Issue
Block a user