Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 102 additions & 30 deletions bin/linux-toolbox
Original file line number Diff line number Diff line change
@@ -1,45 +1,28 @@
#!/usr/bin/env bash

# linux-toolbox – interactive menu front-end for the LinuxScripts utility collection.
# Presents categories and lets the user select a script to run.
# Does not duplicate script logic; invokes utility scripts directly.

# linux-toolbox – CLI dispatcher and interactive menu for LinuxScripts toolkit.
set -euo pipefail

show_help() {
cat <<'EOF'
Usage: linux-toolbox [options]
Usage: linux-toolbox [options] [command] [args...]

Commands:
list List all available utility categories and scripts
run <script_name> [args...] Directly run a utility script (e.g. developer/command-exists bash)
<script_name> [args...] Shortcut to directly run a utility script

Options:
-h, --help Show this help message and exit
-h, --help Show this help message and exit

Description:
Provides a keyboard-friendly menu to launch utility scripts located under
the repository's scripts/ directory. Categories:
1) System
2) Storage
3) Network
4) Processes
5) Packages
6) Hardware
7) SSH
8) Developer
9) Maintenance
10) Exit
When launched without arguments, opens an interactive keyboard menu
to explore and run scripts from the LinuxScripts repository.
EOF
exit 0
}

for arg in "$@"; do
case "$arg" in
-h|--help) show_help ;;
*) echo "Unknown option: $arg" >&2; exit 1 ;;
esac
done

# Resolve repository root relative to script location
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
SCRIPTS_DIR="$REPO_ROOT/scripts"

declare -A CATEGORY_MAP=(
Expand All @@ -54,6 +37,96 @@ declare -A CATEGORY_MAP=(
[9]="maintenance"
)

list_all_scripts() {
echo "=== Available LinuxScripts Utilities ==="
echo ""
for idx in $(echo "${!CATEGORY_MAP[@]}" | tr ' ' '\n' | sort -n); do
cat_name="${CATEGORY_MAP[$idx]}"
cat_dir="$SCRIPTS_DIR/$cat_name"
echo "[$cat_name]"
if [[ -d "$cat_dir" ]]; then
for s in "$cat_dir"/*.sh; do
if [[ -f "$s" ]]; then
s_name="$(basename "$s" .sh)"
echo " - $cat_name/$s_name"
fi
done
fi
echo ""
done
}

find_script() {
local query="$1"
# Strip .sh if user passed it
query="${query%.sh}"

# 1. Exact match category/script
if [[ -f "$SCRIPTS_DIR/$query.sh" ]]; then
echo "$SCRIPTS_DIR/$query.sh"
return 0
fi

# 2. Search by script basename across categories
local matches=()
while IFS= read -r f; do
[[ -n "$f" ]] && matches+=("$f")
done < <(find "$SCRIPTS_DIR" -maxdepth 2 -type f -name "$query.sh" 2>/dev/null || true)

if [[ ${#matches[@]} -eq 1 ]]; then
echo "${matches[0]}"
return 0
elif [[ ${#matches[@]} -gt 1 ]]; then
echo "Ambiguous script name '$query'. Please specify category: e.g. '${matches[0]#"$SCRIPTS_DIR/"}'" >&2
return 1
fi

return 1
}

run_script_cli() {
local target="$1"
shift
local script_path
if ! script_path="$(find_script "$target")"; then
echo "Error: Utility script '$target' not found." >&2
echo "Run 'linux-toolbox list' to view available scripts." >&2
exit 1
fi

exec "$script_path" "$@"
}

# CLI argument handling
if [[ $# -gt 0 ]]; then
case "$1" in
-h|--help)
show_help
;;
list)
list_all_scripts
exit 0
;;
run)
shift
if [[ $# -lt 1 ]]; then
echo "Error: Script name required for 'run' command." >&2
echo "Usage: linux-toolbox run <script_name> [args...]" >&2
exit 1
fi
run_script_cli "$@"
;;
-*)
echo "Error: Unknown option: $1" >&2
show_help
;;
*)
run_script_cli "$@"
;;
esac
fi

# Interactive Menu Mode
main_menu() {
echo ""
echo "=============================="
Expand Down Expand Up @@ -127,7 +200,6 @@ sub_menu() {
echo ""

if [[ -n "$extra_args" ]]; then
# Parse into array to avoid eval vulnerabilities
read -ra arg_arr <<< "$extra_args"
"$selected_script" "${arg_arr[@]}" || echo "Script exited with non-zero status ($?)"
else
Expand Down
112 changes: 88 additions & 24 deletions scripts/process/process-info.sh
Original file line number Diff line number Diff line change
@@ -1,45 +1,109 @@
#!/usr/bin/env bash

set -euo pipefail

show_help() {
cat <<'EOF'
Usage: $(basename "$0") [OPTIONS]

Display information about running processes.
cat <<'EOF'
Usage: process-info.sh [options] [pid|name]

Options:
-a Show all processes (default uses ps -e)
-u USER Filter by user
-h Show this help message
-h, --help Show this help message and exit
-u, --user USER Filter processes by user
-a, --all Show all processes with full details

Description:
Displays detailed process information.
- If a PID is specified, displays status, memory, CPU, and command details for that PID.
- If a process name is specified, lists matching processes.
- If no target is specified, displays top resource-consuming processes.
EOF
exit 0
}

ALL=false
TARGET=""
USER_FILTER=""
while getopts "au:h" opt; do
case $opt in
a) ALL=true ;;
u) USER_FILTER="$OPTARG" ;;
h) show_help; exit 0 ;;
*) show_help; exit 1 ;;
esac
SHOW_ALL=false

while (( "$#" )); do
case "$1" in
-h|--help)
show_help
;;
-u|--user)
if [[ -n "${2-}" && "${2-}" != -* ]]; then
USER_FILTER="$2"
shift
else
echo "Error: Argument for $1 is missing" >&2
exit 1
fi
;;
-a|--all)
SHOW_ALL=true
;;
-*)
echo "Error: Unknown option: $1" >&2
exit 1
;;
*)
if [[ -z "$TARGET" ]]; then
TARGET="$1"
else
echo "Error: Unexpected additional argument: $1" >&2
exit 1
fi
;;
esac
shift
done

if ! command -v ps >/dev/null 2>&1; then
echo "Error: 'ps' command not found." >&2
echo "Error: 'ps' command not found." >&2
exit 1
fi

# Case 1: Target PID provided
if [[ -n "$TARGET" && "$TARGET" =~ ^[0-9]+$ ]]; then
if ! kill -0 "$TARGET" 2>/dev/null; then
echo "Error: Process with PID $TARGET does not exist." >&2
exit 1
fi
echo "=== Process Details for PID $TARGET ==="
ps -p "$TARGET" -o pid,user,%cpu,%mem,stat,start,time,comm,args
exit 0
fi

# Case 2: Target process name provided
if [[ -n "$TARGET" ]]; then
echo "=== Searching processes matching '$TARGET' ==="
MATCHES="$(pgrep -l -f "$TARGET" 2>/dev/null || true)"
if [[ -z "$MATCHES" ]]; then
echo "Error: No processes matching '$TARGET' found." >&2
exit 1
fi
echo "$MATCHES"
exit 0
fi

if $ALL; then
CMD="ps -ef"
else
CMD="ps -e"
# Case 3: Show all or filtered by user
if $SHOW_ALL; then
echo "=== All Running Processes ==="
if [[ -n "$USER_FILTER" ]]; then
ps -u "$USER_FILTER" -o pid,user,%cpu,%mem,stat,start,time,comm
else
ps -eo pid,user,%cpu,%mem,stat,start,time,comm
fi
exit 0
fi

if [[ -n "$USER_FILTER" ]]; then
CMD="$CMD -u $USER_FILTER"
echo "=== Processes for User '$USER_FILTER' ==="
ps -u "$USER_FILTER" -o pid,user,%cpu,%mem,stat,start,time,comm
exit 0
fi

echo "Process list:"
$CMD
# Case 4: Default overview (top CPU and Memory)
echo "=== Top Processes by CPU Usage ==="
ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | head -n 10
echo ""
echo "=== Top Processes by Memory Usage ==="
ps -eo pid,user,%cpu,%mem,comm --sort=-%mem | head -n 10
71 changes: 53 additions & 18 deletions scripts/storage/directory-size.sh
Original file line number Diff line number Diff line change
@@ -1,32 +1,67 @@
#!/usr/bin/env bash

set -euo pipefail

show_help() {
cat <<'EOF'
Usage: $(basename "$0") [OPTIONS] [DIRECTORY]

Display the total size of a directory (including subdirectories).
If DIRECTORY is omitted, the current directory is used.
cat <<'EOF'
Usage: directory-size.sh [options] [directory]

Options:
-h Show this help message
-h, --help Show this help message and exit
-d, --dir DIR Directory to measure (default: current directory)

Description:
Displays the total human-readable disk space used by a directory.
If omitted, measures the current working directory.
EOF
exit 0
}

if [[ "${1-}" == "-h" ]]; then
show_help
exit 0
fi
TARGET_DIR=""

DIR="${1:-.}"
while (( "$#" )); do
case "$1" in
-h|--help)
show_help
;;
-d|--dir)
if [[ -n "${2-}" && "${2-}" != -* ]]; then
TARGET_DIR="$2"
shift
else
echo "Error: Argument for $1 is missing" >&2
exit 1
fi
;;
-*)
echo "Error: Unknown option: $1" >&2
exit 1
;;
*)
if [[ -z "$TARGET_DIR" ]]; then
TARGET_DIR="$1"
else
echo "Error: Unexpected additional argument: $1" >&2
exit 1
fi
;;
esac
shift
done

TARGET_DIR="${TARGET_DIR:-.}"

if [[ ! -d "$TARGET_DIR" ]]; then
echo "Error: '$TARGET_DIR' is not a directory." >&2
exit 1
fi

if [[ ! -d "$DIR" ]]; then
echo "Error: '$DIR' is not a directory" >&2
exit 1
if ! command -v du >/dev/null 2>&1; then
echo "Error: 'du' utility is required but not installed." >&2
exit 1
fi

# Use du to calculate size, suppress errors for inaccessible files.
size=$(du -sh "${DIR}" 2>/dev/null | cut -f1)
REAL_PATH="$(cd "$TARGET_DIR" && pwd -P)"
SIZE="$(du -sh "$REAL_PATH" 2>/dev/null | cut -f1)"

echo "Directory size of '$DIR': $size"
echo "Directory: $REAL_PATH"
echo "Size: $SIZE"
Loading
Loading