Posted on
Artificial Intelligence

Bash Scripts That Answer Linux Questions

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

Bash Scripts That Answer Linux Questions

Ever typed the same diagnostic command three times in one week? Turn those ad‑hoc one‑liners into tiny Bash tools that answer common Linux questions quickly, consistently, and shareably.

In this post, you’ll get a set of small, production-ready Bash scripts that act like answers-on-demand: Which process is using this port? What’s my public IP? Which package owns this command? What changed in /etc? Where did my disk space go?

You’ll also learn how to install any optional tools and how to drop these scripts into your PATH so they’re always one keystroke away.


Why this matters

  • Repeatability: Scripts capture the exact incantation that worked last time.

  • Speed: One short command beats searching shell history or docs.

  • Shareability: Colleagues can reuse and improve your helpers.

  • Learning: Writing a question-focused script forces you to understand the diagnostic flow.


Quick setup: a home for your helpers

1) Create a per-user bin directory and put it in PATH:

mkdir -p "$HOME/bin"
echo 'export PATH="$HOME/bin:$PATH"' >> "$HOME/.bashrc"
# For interactive shells using Zsh:
# echo 'export PATH="$HOME/bin:$PATH"' >> "$HOME/.zshrc"

2) Reload your shell or source your profile:

source "$HOME/.bashrc"

3) Make scripts executable as you add them:

chmod +x "$HOME/bin/ask-*.sh"

1) ask-ip.sh — “What are my local and public IPs?”

This script lists all local IPv4 addresses and tries to discover your public IP with curl (or dig if curl isn’t available).

#!/usr/bin/env bash
set -Eeuo pipefail

public_ip() {
  if command -v curl >/dev/null 2>&1; then
    curl -fsS https://api.ipify.org || return 1
  elif command -v dig >/dev/null 2>&1; then
    dig +short myip.opendns.com @resolver1.opendns.com
  else
    echo "Install curl or dig to query public IP" >&2
    return 1
  fi
}

echo "Local IPv4 addresses:"
ip -4 -o addr show scope global 2>/dev/null | awk '{print " - " $2 ": " $4}'

echo
echo -n "Public IP: "
if ! public_ip; then
  echo "Unknown"
fi

Usage:

ask-ip.sh

Optional installs (if needed):

  • Debian/Ubuntu:

    • sudo apt update && sudo apt install curl dnsutils
  • Fedora/RHEL:

    • sudo dnf install curl bind-utils
  • openSUSE:

    • sudo zypper install curl bind-utils

Notes:

  • ip and ss live in iproute2 and are present on most modern distros by default.

2) ask-port.sh — “Which process is listening on port X?”

Lean on ss (present by default). If installed, lsof provides a richer view.

#!/usr/bin/env bash
set -Eeuo pipefail

usage() {
  echo "Usage: $(basename "$0") <port>"
  exit 1
}

PORT="${1:-}"
[[ -n "$PORT" && "$PORT" =~ ^[0-9]+$ ]] || usage

echo "Using ss to check listeners on TCP port $PORT..."
MATCHES=$(ss -lntp 2>/dev/null | awk -v p=":$PORT" '$4 ~ p')
if [[ -n "$MATCHES" ]]; then
  echo "$MATCHES"
else
  echo "No TCP listeners found on port $PORT via ss."
fi

if command -v lsof >/dev/null 2>&1; then
  echo
  echo "lsof details (if any):"
  # -P: don’t resolve ports; -n: don’t resolve hosts
  lsof -nP -i TCP:"$PORT" -sTCP:LISTEN || true
else
  echo
  echo "Tip: Install lsof for more detail (users/PIDs/fds)."
fi

Usage:

ask-port.sh 8080

Install lsof (optional):

  • Debian/Ubuntu:

    • sudo apt update && sudo apt install lsof
  • Fedora/RHEL:

    • sudo dnf install lsof
  • openSUSE:

    • sudo zypper install lsof

3) ask-owner.sh — “Which package provides this command or file?”

This script resolves a command to its path (if needed) and asks the system package database which package owns it. Works on Debian/Ubuntu (dpkg) and rpm-based distros (Fedora/RHEL/openSUSE).

#!/usr/bin/env bash
set -Eeuo pipefail

usage() {
  echo "Usage: $(basename "$0") <command-or-path>"
  exit 1
}

TARGET="${1:-}"
[[ -n "$TARGET" ]] || usage

# If not a path, try resolving as a command
if [[ "$TARGET" != /* && "$TARGET" != .* && "$TARGET" != ~* ]]; then
  if CMD_PATH=$(command -v -- "$TARGET" 2>/dev/null); then
    TARGET="$CMD_PATH"
  else
    echo "Not found in PATH and not a path: $TARGET" >&2
    exit 2
  fi
fi

if command -v dpkg-query >/dev/null 2>&1 || command -v dpkg >/dev/null 2>&1; then
  dpkg -S -- "$TARGET" || { echo "No owning package found (Debian/Ubuntu)."; exit 1; }
elif command -v rpm >/dev/null 2>&1; then
  rpm -qf -- "$TARGET" || { echo "No owning package found (RPM family)."; exit 1; }
else
  echo "Unsupported package manager. Need dpkg or rpm." >&2
  exit 3
fi

Usage:

ask-owner.sh ssh
ask-owner.sh /usr/bin/ls

Notes:

  • Debian/Ubuntu provide dpkg by default.

  • Fedora/RHEL/openSUSE provide rpm by default.

  • If you’re inside a container/minimal image without package metadata, ownership queries may fail.


4) ask-changed.sh — “What changed recently in /etc?”

List recently modified files in a directory (default: /etc). Adjustable lookback window.

#!/usr/bin/env bash
set -Eeuo pipefail

DIR="${1:-/etc}"
DAYS="${2:-2}"  # files changed within the last N days

if [[ ! -d "$DIR" ]]; then
  echo "Not a directory: $DIR" >&2
  exit 1
fi

echo "Files in $DIR changed within the last $DAYS day(s):"
# GNU find is common on Debian/Ubuntu/Fedora/openSUSE
find "$DIR" -type f -mtime "-$DAYS" -printf '%TY-%Tm-%Td %TH:%TM %p\n' 2>/dev/null | sort

Usage:

ask-changed.sh
ask-changed.sh /var/www 7

Tip:

  • Use -mmin -120 if you want the last 120 minutes instead of days.

5) ask-space.sh — “Where is my disk space going?”

Show the largest subdirectories of a given path (default: /), with consistent numeric sort.

#!/usr/bin/env bash
set -Eeuo pipefail

DIR="${1:-/}"
TOP="${2:-10}"

if [[ ! -d "$DIR" ]]; then
  echo "Not a directory: $DIR" >&2
  exit 1
fi

# Use bytes for accurate sort, then pretty-print
du -x -B1 -d1 -- "$DIR" 2>/dev/null \
  | sort -n \
  | tail -n "$TOP" \
  | awk '{bytes=$1; $1=""; sub(/^ +/,""); path=$0;
         cmd="numfmt --to=iec --suffix=B " bytes;
         cmd | getline human; close(cmd);
         print human "\t" path }'

Usage:

ask-space.sh
ask-space.sh /var 15

Notes:

  • numfmt is part of GNU coreutils and is typically present. If missing, replace the awk block with a simple sort -h pipeline and accept human-sort limitations.

Real-world usage flow

  • Investigate a web issue:

    • ask-port.sh 443 to see if anything is listening.
    • ask-owner.sh nginx to confirm the package and path actually in use.
    • ask-changed.sh /etc/nginx 3 to check for config edits in the last 3 days.
    • ask-ip.sh to confirm the server’s public and local IPs.
  • When disk alerts fire:

    • ask-space.sh / 20 to quickly spot the biggest offenders.

Wrap-up and next steps

You now have question-driven Bash helpers you can extend:

  • Add -h/--help flags and usage text to each script.

  • Compose scripts: one script can call another for richer answers.

  • Version your ~/bin directory in git and share with your team.

  • Add completions/aliases for muscle-memory convenience.

Call to action:

  • Pick one recurring question you asked this week and turn it into a script today. Save it to ~/bin, make it executable, and share it in your team chat. Your future self (and your teammates) will thank you.