Skip to main content
The runtime module provides comprehensive functions to detect and query the bash execution environment, including terminal type, shell options, system information, and environment capabilities.

Terminal detection

Functions for checking terminal and TTY status.
Check if all standard file descriptors (stdin, stdout, stderr) are connected to a terminal.
runtime.sh:2
runtime::is_terminal() {
  # Thorough check for all standard file descriptors (stdin, stdout, stderr)
  [[ -t 0 && -t 1 && -t 2 ]]
}
Usage:
if runtime::is_terminal; then
  echo "Running in a terminal"
fi
Check if stdin is connected to a terminal.
runtime.sh:7
runtime::is_terminal::stdin() {
  [[ -t 0 ]]
}
Check if stdout is connected to a terminal.
runtime.sh:11
runtime::is_terminal::stdout() {
  [[ -t 1 ]]
}
Check if stderr is connected to a terminal.
runtime.sh:15
runtime::is_terminal::stderr() {
  [[ -t 2 ]]
}
Check if we have a controlling terminal.
runtime.sh:277
runtime::is_tty() {
  # Check if we have a controlling terminal
  [[ -t 0 ]] && tty -s 2>/dev/null
}
Get the name of the current TTY.
runtime.sh:282
runtime::tty_name() {
  tty 2>/dev/null || echo "not a tty"
}
Usage:
echo "Current TTY: $(runtime::tty_name)"
# Output: Current TTY: /dev/pts/0
Check if we’re running in a pseudo-terminal.
runtime.sh:286
runtime::is_pty() {
  # Check if we're in a pseudo-terminal
  [[ "$(tty)" =~ ^/dev/pts/[0-9]+ ]]
}

Shell state detection

Functions to check bash options and shell execution modes.
Check if shell tracing (set -x) is enabled.
runtime.sh:19
runtime::is_traced() {
    [[ "$-" == *x* ]] || [[ -n "$BASH_XTRACEFD" ]]
}
Check if verbose mode (set -v) is enabled.
runtime.sh:23
runtime::is_verbose() {
    [[ "$-" == *v* ]]
}
Check if errexit (set -e) is enabled.
runtime.sh:27
runtime::errexit_enabled() {
    [[ "$-" == *e* ]]
}
Check if nounset (set -u) is enabled.
runtime.sh:31
runtime::nounset_enabled() {
    [[ "$-" == *u* ]]
}
Check if noclobber (set -C) is enabled.
runtime.sh:35
runtime::noclobber_enabled() {
    [[ "$-" == *C* ]]
}
Check if running in an interactive shell.
runtime.sh:39
runtime::is_interactive() {
  [[ $- == *i* ]]
}
Check if a specific shell flag is set.
runtime.sh:43
runtime::has_flag() {
    local flag="$1"
    [[ "$-" == *"$flag"* ]]
}
Usage:
if runtime::has_flag e; then
  echo "errexit is enabled"
fi
Check if running in a login shell.
runtime.sh:48
runtime::is_login() {
  shopt -q login_shell
}
Check if the script is being sourced (not executed).
runtime.sh:52
runtime::is_sourced() {
  [[ "${BASH_SOURCE[0]}" != "${0}" ]]
}
Check if running in bash.
runtime.sh:56
runtime::is_bash() {
  [[ -n "$BASH_VERSION" ]]
}
Check if stdin is coming from a pipe.
runtime.sh:60
runtime::is_pipe() {
  # Check if stdin is a pipe
  [[ -p /dev/stdin ]] && return 0

  # Check if stdin is redirected from a file
  [[ ! -t 0 ]] && return 0

  # Only check jobs if we're not interactive
  if ! runtime::is_interactive && [[ -n "$(jobs -p)" ]]; then
    return 0
  fi

  return 1
}
Check if any standard descriptor is redirected.
runtime.sh:75
runtime::is_redirected() {
  # Check if any std descriptor is redirected
  [[ ! -t 0 ]] || [[ ! -t 1 ]] || [[ ! -t 2 ]]
}
Check if running in a subshell.
runtime.sh:80
runtime::is_subshell() {
    [[ "$BASH_SUBSHELL" -gt 0 ]]
}
Check if job control (set -m) is enabled.
runtime.sh:84
runtime::job_controlled() {
    [[ "$-" == *m* ]]
}
Check if a DEBUG trap is set.
runtime.sh:88
runtime::debug_trapped() {
    [[ -n "$(trap -p DEBUG)" ]]
}
Check if brace expansion is enabled.
runtime.sh:92
runtime::braceexpand_enabled() {
    [[ "$-" == *B* ]]
}
Check if history expansion is enabled.
runtime.sh:96
runtime::histexpand_enabled() {
    [[ "$-" == *H* ]]
}
Check if physical directory mode (set -P) is enabled.
runtime.sh:100
runtime::physical_cd_enabled() {
    [[ "$-" == *P* ]]
}

Environment detection

Functions to detect system properties and user privileges.
Check if a command is available in PATH.
runtime.sh:105
runtime::has_command() {
  command -v "$1" >/dev/null 2>&1
}
Usage:
if runtime::has_command git; then
  echo "Git is installed"
fi
Check if running as root user.
runtime.sh:109
runtime::is_root() {
  [[ $EUID -eq 0 ]]
}
Check if running in a desktop environment.
runtime.sh:113
runtime::is_desktop() {
  [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ]
}
Get the name of the system init process.
runtime.sh:117
runtime::sysinit() {
  ps -p 1 -o comm=
}
Usage:
echo "Init system: $(runtime::sysinit)"
# Output: Init system: systemd
Check if running under sudo.
runtime.sh:121
runtime::is_sudo() {
  [[ -n "$SUDO_USER" ]]
}
Check if running in a CI environment.
runtime.sh:126
runtime::is_ci() {
  [[ -n "$CI" ]] ||
    [[ -n "$GITHUB_ACTIONS" ]] ||
    [[ -n "$GITLAB_CI" ]] ||
    [[ -n "$CIRCLECI" ]] ||
    [[ -n "$TRAVIS" ]] ||
    [[ -n "$JENKINS_URL" ]] ||
    [[ -n "$BITBUCKET_BUILD_NUMBER" ]] ||
    [[ -n "$TEAMCITY_VERSION" ]] ||
    [[ -n "$DRONE" ]] ||
    [[ -n "$CODEBUILD_BUILD_ID" ]] ||
    [[ -n "$AZURE_HTTP_USER_AGENT" ]] ||
    [[ -n "$BUILDKITE" ]]
}
Supported CI platforms:
  • GitHub Actions
  • GitLab CI
  • CircleCI
  • Travis CI
  • Jenkins
  • Bitbucket Pipelines
  • TeamCity
  • Drone
  • AWS CodeBuild
  • Azure DevOps
  • Buildkite
Execute a command with root privileges using available escalation methods.
runtime.sh:149
runtime::exec_root() {
  # Already root, nothing to do
  if runtime::is_root; then
    return 0
  fi

  if runtime::has_command sudo; then
    # In a non-terminal context, check if sudo can run without a password prompt
    # -n flag makes sudo fail immediately instead of hanging if password is needed
    if ! runtime::is_terminal && ! sudo -n true 2>/dev/null; then
      echo "runtime::request_root: sudo requires a password but no terminal is available, will attempt alternatives." >&2
      # Fall through to other methods
    else
      sudo "$@"
      return $?
    fi
  fi

  if runtime::has_command pkexec && runtime::is_desktop; then
    pkexec "$@"
  elif runtime::has_command doas; then
    doas "$@"
  elif runtime::has_command su; then
    # su -c takes a single string, fragile with spaces in arguments
    su -c "exec $(printf '%q ' "$@")" root
  else
    echo "runtime::request_root: no privilege escalation method found" >&2
    return 1
  fi
}
Tries these methods in order:
  1. sudo (if available and can run without password in non-terminal contexts)
  2. pkexec (if in desktop environment)
  3. doas (OpenBSD alternative to sudo)
  4. su (fallback)

Platform detection

Functions to detect operating system, architecture, and distribution.
Check if running in Windows Subsystem for Linux.
runtime.sh:180
runtime::is_wsl() {
  [[ -f /proc/version ]] && grep -qi "microsoft" /proc/version
}
Get the operating system name.
runtime.sh:184
runtime::os() {
  if runtime::is_wsl; then
    echo "wsl"
    return
  fi

  case "$(uname -s)" in
  Linux*) echo "linux" ;;
  Darwin*) echo "darwin" ;;
  CYGWIN*) echo "cygwin" ;;
  MINGW*) echo "mingw" ;;
  *) echo "unknown" ;;
  esac
}
Returns: linux, darwin, wsl, cygwin, mingw, or unknown
Get the CPU architecture.
runtime.sh:199
runtime::arch() {
  case "$(uname -m)" in
  x86_64) echo "amd64" ;;
  i386) echo "386" ;;
  armv7l) echo "armv7" ;;
  aarch64) echo "arm64" ;;
  *) echo "unknown" ;;
  esac
}
Returns: amd64, 386, armv7, arm64, or unknown
Get the Linux distribution ID.
runtime.sh:209
runtime::distro() {
  if [[ -f /etc/os-release ]]; then
    (. /etc/os-release && echo "$ID")
  else
    echo "unknown"
  fi
}
Usage:
echo "Distribution: $(runtime::distro)"
# Output: Distribution: ubuntu
Get the kernel version number (Linux only).
runtime.sh:141
runtime::kernel_version() {
  [[ $(runtime::os) == "linux" ]] || return 1
  # Number only, case of checks where you don't care about types
  local v
  v=$(uname -r)
  printf '%s\n' "${v%%-*}"
}
Usage:
echo "Kernel version: $(runtime::kernel_version)"
# Output: Kernel version: 5.15.0

Bash version detection

Functions to check bash version information.
Get the full bash version.
runtime.sh:217
runtime::bash_version() {
  echo "${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}.${BASH_VERSINFO[2]}"
}
Usage:
echo "Bash version: $(runtime::bash_version)"
# Output: Bash version: 5.1.16
Get the major bash version number.
runtime.sh:221
runtime::bash_version::major() {
  echo "${BASH_VERSINFO[0]}"
}
Check if bash version meets minimum requirement (defaults to 3).
runtime.sh:226
runtime::is_minimum_bash() {
  ((BASH_VERSINFO[0] >= ${1:-3}))
}
Usage:
if runtime::is_minimum_bash 4; then
  echo "Bash 4 or higher"
fi

Container and virtualization

Functions to detect container and virtual machine environments.
Check if running in a container.
runtime.sh:230
runtime::is_container() {
  [[ -f /.dockerenv ]] ||
  [[ -f /run/.containerenv ]] ||
  grep -q "docker\|lxc\|kubepods" /proc/1/cgroup 2>/dev/null ||
  [[ -n "$CONTAINER" ]] ||
  [[ -n "$KUBERNETES_SERVICE_HOST" ]]
}
Detects:
  • Docker
  • Podman
  • LXC
  • Kubernetes pods
Check if running in a virtual machine.
runtime.sh:292
runtime::is_virtualized() {
  if [[ $(runtime::os) == "linux" ]]; then
    if [[ -f /proc/cpuinfo ]]; then
      grep -q "hypervisor" /proc/cpuinfo && return 0
    fi
    if [[ -f /sys/class/dmi/id/product_name ]]; then
      local product
      product=$(cat /sys/class/dmi/id/product_name 2>/dev/null)
      [[ "$product" =~ (VirtualBox|VMware|KVM|QEMU|Xen|Hyper-V) ]] && return 0
    fi
  fi
  return 1
}
Detects:
  • VirtualBox
  • VMware
  • KVM
  • QEMU
  • Xen
  • Hyper-V

Terminal capabilities

Functions to detect terminal features.
Check if the terminal supports color output.
runtime.sh:238
runtime::supports_color() {
  # Check if terminal supports color
  [[ -t 1 ]] && [[ "$TERM" != "dumb" ]] && {
    [[ -n "$COLORTERM" ]] ||
    [[ "$TERM" =~ ^(xterm|screen|vt100|linux|ansi) ]] || {
      local colors
      colors=$(tput colors 2>/dev/null)
      [[ -n "$colors" && "$colors" -ge 8 ]]
    }
  }
}
Check if the terminal supports 24-bit true color.
runtime.sh:251
runtime::supports_truecolor() {
  [[ -n "$COLORTERM" ]] && [[ "$COLORTERM" =~ ^(truecolor|24bit) ]]
}

Multiplexer detection

Functions to detect terminal multiplexers.
Check if running inside a terminal multiplexer.
runtime.sh:255
runtime::is_multiplexer() {
  [[ -n "$STY" ]] || [[ -n "$TMUX" ]]
}
Check if running inside tmux.
runtime.sh:259
runtime::is_tmux() {
  [[ -n "$TMUX" ]]
}
Get the current screen/tmux session name.
runtime.sh:263
runtime::screen_session() {
  echo "${STY:-${TMUX:-none}}"
}

SSH detection

Functions to detect SSH sessions.
Check if running in an SSH session.
runtime.sh:267
runtime::is_ssh() {
  [[ -n "$SSH_CLIENT" ]] ||
  [[ -n "$SSH_TTY" ]] ||
  [[ -n "$SSH_CONNECTION" ]]
}
Get the SSH client IP address.
runtime.sh:273
runtime::ssh_client() {
  echo "${SSH_CLIENT%% *}"  # First part is client IP
}

Package manager detection

Function to detect the system package manager.
Detect the system package manager.
runtime.sh:307
runtime::pm() {
  if runtime::has_command apt-get; then
    echo "apt"
  elif runtime::has_command pacman; then
    echo "pacman"
  elif runtime::has_command dnf; then
    echo "dnf"
  elif runtime::has_command yum; then
    echo "yum"
  elif runtime::has_command zypper; then
    echo "zypper"
  elif runtime::has_command apk; then
    echo "apk"
  elif runtime::has_command brew; then
    echo "brew"
  elif runtime::has_command pkg; then
    echo "pkg"
  elif runtime::has_command xbps-install; then
    echo "xbps"
  elif runtime::has_command nix-env; then
    echo "nix"
  else
    echo "unknown"
  fi
}
Supports:
  • apt (Debian/Ubuntu)
  • pacman (Arch)
  • dnf/yum (Fedora/RHEL)
  • zypper (openSUSE)
  • apk (Alpine)
  • brew (macOS/Linux)
  • pkg (FreeBSD)
  • xbps (Void Linux)
  • nix (NixOS)

Build docs developers (and LLMs) love