/.bashrc

Slug: bashrc

36968 characters 4849 words

#Introduction

This guide walks through configuring a robust interactive shell on Debian 11 “Bullseye,” including environment variables (Go, Rust, Python), Flatpak, aliases, and a systemd-user–managed SSH agent. It separates user-level and root-level steps, clarifies placeholders, and includes verification commands.


#1. System Update & Core Utilities

sudo apt update && sudo apt upgrade -y sudo apt install -y \ build-essential git curl wget unzip zip bash-completion \ python3-pip nodejs npm libpulse-dev flatpak swaks

#2. Language Runtimes

#Go (≥1.20)

GO_VER=1.20.5 wget https://go.dev/dl/go${GO_VER}.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz rm go${GO_VER}.linux-amd64.tar.gz

#Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y

#3. Shell Configuration

#3.1 ~/.bash_profile (User)

# Source ~/.bashrc for interactive login shells if [[ $- == *i* ]]; then source ~/.bashrc fi

#3.2 ~/.bashrc (User)

# 1. Exit if not interactive case "$-" in *i*) ;; *) return;; esac # 2. History HISTCONTROL=ignoreboth # space-prefixed commands and duplicates are not saved shopt -s histappend # Append to history file, don't overwrite HISTSIZE=5000 # Number of commands to keep in memory HISTFILESIZE=10000 # Number of commands to keep in the history file # Save history after each command and reload it to make it available across terminals. # `history -a` appends the current session's history to HISTFILE. # `PROMPT_COMMAND="history -a; ${PROMPT_COMMAND}"` ensures this happens before each prompt. # Rely on histappend for merging on shell exit. PROMPT_COMMAND="history -a; ${PROMPT_COMMAND}" # 3. XDG directories export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-/root/.config}" export XDG_CACHE_HOME="${XDG_CACHE_HOME:-/root/.cache}" export XDG_DATA_HOME="${XDG_DATA_HOME:-/root/.local/share}" # Ensure critical XDG directories exist mkdir -p "$XDG_CONFIG_HOME" "$XDG_CACHE_HOME" "$XDG_DATA_HOME" # Append Flatpak XDG data dirs to the system default XDG_DATA_DIRS _FLATPAK_USER_DATA_DIR="$XDG_DATA_HOME/flatpak/exports/share" _FLATPAK_SYSTEM_DATA_DIR="/var/lib/flatpak/exports/share" _SYSTEM_XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}" export XDG_DATA_DIRS="${_FLATPAK_USER_DATA_DIR}:${_FLATPAK_SYSTEM_DATA_DIR}:${_SYSTEM_XDG_DATA_DIRS}" # Clean up temporary variables unset _FLATPAK_USER_DATA_DIR _FLATPAK_SYSTEM_DATA_DIR _SYSTEM_XDG_DATA_DIRS # XDG_RUNTIME_DIR is critical and typically set by pam_systemd. # If it's not set, it indicates a problem with the system's session management (e.g., pam_systemd). # Do not attempt to set it manually to a /tmp path here as it can cause issues. if [ -z "$XDG_RUNTIME_DIR" ]; then # Log an error or warning if preferred, but avoid setting a non-standard fallback # echo "Warning: XDG_RUNTIME_DIR is not set. User services may not function correctly." >&2 : # No action, rely on system setup else export XDG_RUNTIME_DIR # Ensure it's exported if set by pam_systemd fi # 4. PATH updates export GOPATH="/root/go" _add_to_path_if_missing() { local dir_to_add="$1" local prepend="$2" # "prepend" or "append" if [ -d "$dir_to_add" ]; then case ":$PATH:" in *":$dir_to_add:"*) :;; # Already in PATH *) if [ "$prepend" = "prepend" ]; then PATH="$dir_to_add:$PATH" # Prepend for higher priority else PATH="$PATH:$dir_to_add" # Append fi ;; esac fi } _add_to_path_if_missing "/usr/local/go/bin" "prepend" # Go system binaries _add_to_path_if_missing "$GOPATH/bin" "prepend" # User-installed Go binaries _add_to_path_if_missing "/root/.local/bin" "prepend" # User-local pip installs, etc. # Rust path is handled by sourcing .cargo/env, which also prepends. unset _add_to_path_if_missing export PATH # 5. Rust environment [ -f "/root/.cargo/env" ] && source "/root/.cargo/env" # 6. Bash completion if ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then source /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then source /etc/bash_completion fi fi # 7. SSH agent: Prioritize systemd-user, then GNOME Keyring if in desktop session # This logic determines which SSH_AUTH_SOCK to use. # Path for the systemd user ssh-agent socket _SYSTEMD_SSH_AGENT_SOCK="$XDG_RUNTIME_DIR/ssh-agent.sock" if [ -n "$XDG_RUNTIME_DIR" ] && [ -S "$_SYSTEMD_SSH_AGENT_SOCK" ]; then # systemd user agent socket exists, use it. export SSH_AUTH_SOCK="$_SYSTEMD_SSH_AGENT_SOCK" elif [ -n "$DESKTOP_SESSION" ] && command -v gnome-keyring-daemon >/dev/null; then # No systemd user agent socket found (or XDG_RUNTIME_DIR not set), # but in a desktop session. Attempt to use/start GNOME Keyring. # GNOME Keyring might already be running via its own systemd user service or XDG autostart. # This eval will set SSH_AUTH_SOCK if gnome-keyring-daemon starts/is running and manages SSH. eval "$(gnome-keyring-daemon --start --components=secrets,ssh)" export SSH_AUTH_SOCK # Ensure it's exported from eval fi unset _SYSTEMD_SSH_AGENT_SOCK # Attempt to add default SSH key (id_rsa) if an agent is running and has no keys. if command -v ssh-add >/dev/null; then if ! ssh-add -l &>/dev/null; then # Check if agent has ANY keys if [ -n "${SSH_AUTH_SOCK}" ] && [ -S "${SSH_AUTH_SOCK}" ] && [ -f "/root/.ssh/id_rsa" ]; then # Agent seems to be running (socket exists), but no keys listed. Add id_rsa. # Suppress errors (e.g., passphrase needed but no tty, or key already added by another mechanism). ssh-add "/root/.ssh/id_rsa" 2>/dev/null || true fi fi fi # 9. Prompt if [[ "${EUID}" == "0" ]]; then # Root prompt PS1='\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] ' else # User prompt PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' fi # 10. Aliases (!!! REVIEW AND REPLACE PLACEHOLDERS !!!) alias ls='ls --color=auto -hF' # Added -h for human-readable sizes, -F for type indicators alias ll='ls -alFh' # Added -h alias la='ls -Ah' # Added -h alias l='ls -CFh' # Added -h alias grep='grep --color=auto' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' # Example ping alias (uses default system ping) alias p='ping -c 4 ib.bsb.br' # Pings example.com 4 times # Swaks alias for email testing # !!! REPLACE with your actual email, app password, and possibly SMTP server !!! # For Gmail, you'll need an "App Password". See Google's help documentation. # alias Z='swaks -4 -tls -f you@gmail.com -t recipient@example.com -s smtp.gmail.com:587 -au you@gmail.com -ap YOUR_GMAIL_APP_PASSWORD -d' alias Z='echo "Swaks alias Z not configured. Edit ~/.bashrc with your email details and an App Password for services like Gmail."' # Git project aliases # !!! REPLACE 'REPO' with your actual repository directory name if different !!! # And ensure ~/projects/REPO is a git repository. PROJECTS_DIR="/root/projects" # Example: alias project1-pull='(cd "$PROJECTS_DIR/my-actual-project" && git pull) || echo "Failed to cd or pull in $PROJECTS_DIR/my-actual-project"' alias pullrepo='(cd "$PROJECTS_DIR/REPO" && git pull) || echo "Failed to cd to $PROJECTS_DIR/REPO or pull"' alias pushrepo='(cd "$PROJECTS_DIR/REPO" && git push) || echo "Failed to cd to $PROJECTS_DIR/REPO or push"' # Update system alias update='sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y && sudo apt clean && echo "System update process completed."' # Check for listening ports alias listports='sudo ss -tulnp'

#4. systemd-user SSH Agent Service (User)

Create ~/.config/systemd/user/ssh-agent.service:

[Unit] Description=SSH Agent per user After=network.target [Service] Type=forking Environment=SSH_AUTH_SOCK=%t/ssh-agent.sock ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK [Install] WantedBy=default.target

Enable and start:

systemctl --user daemon-reload systemctl --user enable ssh-agent.service systemctl --user start ssh-agent.service

Verify:

systemctl --user status ssh-agent.service ls -l "$XDG_RUNTIME_DIR/ssh-agent.sock" ssh-add -l

#5. Common SSH Use Cases

  • Passwordless login: Key-based server access.
  • Git over SSH: Seamless git clone/push/pull.
  • Agent forwarding: Secure multi-hop SSH.
  • Hardware tokens: GNOME Keyring integration.

#6. Verification Checklist

go version rustc --version bash --login -ic 'echo interactive' ssh-add -l

#installing the necessary dependencies

This comprehensive guide will walk you through installing and configuring every dependency and necessity to fully implement the features of your provided .bashrc configuration and SSH setup on a Debian 11 “Bullseye” system. It assumes your root user is root and your local user is linaro.

User Account Assumption:

  • Root user: root
  • Local user: linaro

#Prerequisites for linaro User

Before starting, ensure the linaro user has sudo privileges to execute administrative commands. If not, as the root user, run:

# As root user usermod -aG sudo linaro

After running this command, linaro must log out and log back in for the group change to take effect. All commands prefixed with sudo below should be run by the linaro user, leveraging these sudo privileges.


#Part 1: System-Wide Installations and Configurations (executed by linaro using sudo)

These steps involve installing packages and setting up system-level configurations.

#1.1. System Update

First, ensure your system’s package list and installed packages are up-to-date:

sudo apt update && sudo apt upgrade -y
  • What: Updates the local package lists from repositories and upgrades all currently installed packages to their newest versions.
  • Why: Essential for system stability, security, and to ensure compatibility with new software.
  • Verification: The commands complete without errors. You can run sudo apt list --upgradable afterwards; it should show no or very few packages.

#1.2. Core Utilities and Essential Packages

Install the core utilities and packages mentioned in your script, plus a few others that are implicitly needed or highly recommended for the setup:

sudo apt install -y \ build-essential \ git \ curl \ wget \ unzip \ zip \ bash-completion \ python3-pip \ nodejs \ npm \ libpulse-dev \ flatpak \ swaks \ openssh-client \ iputils-ping \ gnome-keyring \ libnss-myhostname \ dbus-user-session

Let’s break down why each of these is needed:

  • build-essential:
    • What: A meta-package that installs GCC (C compiler), make, and other essential tools for compiling software from source.
    • Why: Required by Rust’s installation script (rustup) and potentially for other software you might build.
    • Verify: gcc --version and make --version should display their versions.
  • git:
    • What: A distributed version control system.
    • Why: Needed for the pull and push aliases in your .bashrc (interacting with ~/projects/REPO) and potentially by rustup.
    • Verify: git --version should display the installed version.
  • curl:
    • What: A command-line tool for transferring data using various network protocols.
    • Why: Used to download the Rust installation script (sh.rustup.rs).
    • Verify: curl --version should display its version.
  • wget:
    • What: A command-line tool for downloading files from the web.
    • Why: Used to download the Go language tarball.
    • Verify: wget --version should display its version.
  • unzip & zip:
    • What: Utilities for decompressing and creating ZIP archives, respectively.
    • Why: General-purpose utilities useful for managing compressed files.
    • Verify: unzip -v and zip -v should display their versions.
  • bash-completion:
    • What: Provides programmable command-line completion for the Bash shell.
    • Why: Your .bashrc explicitly sources bash completion scripts, enhancing shell interactivity (e.g., pressing Tab to complete commands or options).
    • Verify: After setting up .bashrc and opening a new terminal, typing a command like apt ins and pressing Tab should offer install as a suggestion.
  • python3-pip:
    • What: The package installer for Python 3.
    • Why: While not directly called by a .bashrc function, it’s useful for Python development. Python scripts installed via pip for the user might go into $HOME/.local/bin, which is added to your PATH.
    • Verify: pip3 --version should display its version.
  • nodejs & npm:
    • What: Node.js is a JavaScript runtime; npm is its package manager.
    • Why: Common tools for web development and various JavaScript-based utilities. Not directly used by .bashrc but good for a development setup.
    • Verify: node --version and npm --version should display their versions.
  • libpulse-dev:
    • What: Development files for PulseAudio, a sound server.
    • Why: Often a dependency for desktop applications or development involving audio. Its inclusion might be related to expectations in a desktop environment where GNOME Keyring is also used.
    • Verify: dpkg -s libpulse-dev | grep Status should show “install ok installed”.
  • flatpak:
    • What: A system for building, distributing, and running sandboxed desktop applications.
    • Why: Your .bashrc modifies XDG_DATA_DIRS to include Flatpak paths, making applications installed via Flatpak discoverable.
    • Verify: flatpak --version should display its version.
  • swaks:
    • What: “Swiss Army Knife for SMTP,” a command-line SMTP testing tool.
    • Why: Used by the Z alias in your .bashrc for sending test emails.
    • Verify: swaks --version should display its version.
  • openssh-client:
    • What: Provides SSH client tools like ssh, scp, ssh-agent, ssh-add, and ssh-keygen.
    • Why: Essential for all SSH functionalities: agent management, key generation, connecting to SSH servers, and for the ssh-add command in .bashrc.
    • Verify: ssh -V should display its version.
  • iputils-ping:
    • What: Provides the ping utility.
    • Why: Required for the p alias in your .bashrc.
    • Verify: ping -V should display its version (use Ctrl+C to stop if it starts pinging).
  • gnome-keyring:
    • What: A daemon that keeps passwords and other secrets for users. It can also manage SSH keys.
    • Why: Your .bashrc includes a fallback mechanism to use gnome-keyring-daemon as an SSH agent if a DESKTOP_SESSION is active.
    • Verify: dpkg -s gnome-keyring | grep Status should show “install ok installed”.
  • libnss-myhostname:
    • What: A plugin for NSS providing hostname resolution for the locally configured system hostname.
    • Why: Crucial for the stability of systemd --user services, ensuring the local hostname is consistently resolvable, preventing potential issues with services that rely on it, especially in minimal or containerized environments.
    • Verify: dpkg -s libnss-myhostname | grep Status should show “install ok installed”.
  • dbus-user-session:
    • What: Provides D-Bus session management for user sessions, often launched via systemd --user.
    • Why: Essential for proper functioning of the systemd user instance (systemd --user), which manages user-specific services like the ssh-agent.service. It ensures the user’s D-Bus is available, which many modern applications and services rely on, and helps manage XDG_RUNTIME_DIR.
    • Verify: dpkg -s dbus-user-session | grep Status should show “install ok installed”.

#1.3. Install Go Language (System Part)

This installs Go into /usr/local/go, accessible by all users. (Assumes linux-amd64 architecture).

# To find the latest Go version, visit https://go.dev/dl/ # As of May 2025, a recent stable version is 1.22.3. Please check for the latest. GO_VER="1.22.3" # Example: Update this to the latest desired stable version. GO_ARCH="amd64" # Adjust if your architecture is different (e.g., arm64) # Download Go binary tarball (as linaro) wget "https://go.dev/dl/go${GO_VER}.linux-${GO_ARCH}.tar.gz" -P /tmp # Extract Go to /usr/local (needs sudo) sudo tar -C /usr/local -xzf "/tmp/go${GO_VER}.linux-${GO_ARCH}.tar.gz" # Remove the downloaded tarball (as linaro) rm "/tmp/go${GO_VER}.linux-${GO_ARCH}.tar.gz"
  • What: Installs the Go programming language binaries.
  • Why: Your .bashrc sets GOPATH and adds /usr/local/go/bin to the PATH for using Go commands.
  • Verification (later, after .bashrc is configured): go version

#Part 2: User-Specific Installations and Configurations (as linaro)

These steps are performed by the linaro user and configure their specific environment.

#2.1. Create User-Specific Directories

Your .bashrc and language tools expect certain directories in linaro’s home.

# For Go development (GOPATH) mkdir -p "$HOME/go/bin" "$HOME/go/pkg" "$HOME/go/src" # For XDG Base Directory Specification & systemd user services mkdir -p "$HOME/.config/systemd/user" chmod 0700 "$HOME/.config" # Ensure parent .config dir is secure chmod 0700 "$HOME/.config/systemd" chmod 0700 "$HOME/.config/systemd/user" # Secure user service definitions mkdir -p "$HOME/.local/share/flatpak/exports/share" # For user-installed Flatpak data mkdir -p "$HOME/.local/bin" # For user-specific executables (pip might install here) # For project alias examples mkdir -p "$HOME/projects/REPO" # Replace REPO with your actual project name if desired # You would then 'git init' or 'git clone' into ~/projects/REPO
  • What: Creates standard directory structures used by Go, XDG-compliant applications, Flatpak, pip, and your example aliases. Ensures correct permissions for systemd user directories.
  • Why: Ensures these tools and configurations function correctly and securely.
  • Verification: ls -ld "$HOME/go", stat -c "%a %n" "$HOME/.config/systemd/user" etc., should show the created directories with appropriate permissions (e.g., 700 for ~/.config/systemd/user).

#2.2. Install Rust Language

Rust is installed per-user using rustup.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
  • What: Downloads and runs rustup-init.sh, which installs rustup (the Rust toolchain manager) and the latest stable Rust toolchain (compiler rustc, package manager cargo, etc.) into $HOME/.cargo.
  • Why: Your .bashrc sources $HOME/.cargo/env to add Rust tools to your PATH.
  • Verification (later, after .bashrc is configured): rustc --version and cargo --version. You might need to source $HOME/.cargo/env manually for the current session before editing .bashrc: source "$HOME/.cargo/env".

#2.3. Generate SSH Key Pair

If linaro doesn’t already have an SSH key, generate one. This key (~/.ssh/id_rsa) will be added to the SSH agent.

# Check if a key already exists if [ ! -f "$HOME/.ssh/id_rsa" ]; then echo "SSH key not found. Generating a new one..." # Generate with a comment including username and hostname (or 'debian' if hostname fails) ssh-keygen -t rsa -b 4096 -C "linaro@$(hostname || echo debian)" echo "SSH key generated." else echo "SSH key $HOME/.ssh/id_rsa already exists." fi # Ensure correct permissions for .ssh directory and its contents chmod 700 "$HOME/.ssh" [ -f "$HOME/.ssh/id_rsa" ] && chmod 600 "$HOME/.ssh/id_rsa" [ -f "$HOME/.ssh/id_rsa.pub" ] && chmod 644 "$HOME/.ssh/id_rsa.pub" # Apply strict permissions to other common SSH files if they exist [ -f "$HOME/.ssh/authorized_keys" ] && chmod 600 "$HOME/.ssh/authorized_keys" [ -f "$HOME/.ssh/known_hosts" ] && chmod 600 "$HOME/.ssh/known_hosts" [ -f "$HOME/.ssh/config" ] && chmod 600 "$HOME/.ssh/config"
  • What: ssh-keygen creates a private (id_rsa) and public (id_rsa.pub) key pair.
  • Why: The private key is used for authenticating to SSH servers (e.g., for passwordless login, Git operations). The .bashrc script attempts to ssh-add ~/.ssh/id_rsa.
  • During generation: You’ll be asked for a file to save the key (press Enter for default) and a passphrase (optional, but highly recommended for security). The SSH agent will help manage this passphrase so you don’t have to type it repeatedly.
  • Verification: ls -al "$HOME/.ssh/id_rsa" should show the private key file with 600 permissions.

#2.4. Configure ~/.bash_profile

This file ensures .bashrc is loaded for interactive login shells (e.g., when you SSH into the linaro account or log in on the console).

cat << 'EOF' > "$HOME/.bash_profile" # Source ~/.bashrc for interactive login shells # Check if running interactively and if .bashrc exists if [[ $- == *i* && -f "$HOME/.bashrc" ]]; then source "$HOME/.bashrc" fi # Fallback PATH adjustments (though .bashrc should handle these comprehensively) # This ensures .local/bin and .cargo/bin are in PATH even if .bashrc is minimal. _add_to_path_if_missing() { if [ -d "$1" ]; then case ":$PATH:" in *":$1:"*) :;; # Already in PATH *) PATH="$1:$PATH" ;; # Prepend esac fi } _add_to_path_if_missing "$HOME/.local/bin" _add_to_path_if_missing "$HOME/.cargo/bin" # Rustup typically handles this via .profile modification too unset _add_to_path_if_missing export PATH EOF
  • What: Configures Bash to source ~/.bashrc upon login.
  • Why: Makes your aliases, PATH settings, and other .bashrc configurations available immediately after logging in.
  • Verification (later, after full setup): bash --login -ic 'type ll' should show that ll is an alias.

#2.5. Configure ~/.bashrc

Create or replace ~/.bashrc with your provided configuration. Important: Review the aliases section and replace placeholders.

cat << 'EOF' > "$HOME/.bashrc" # 1. Exit if not interactive case "$-" in *i*) ;; *) return;; esac # 2. History HISTCONTROL=ignoreboth # space-prefixed commands and duplicates are not saved shopt -s histappend # Append to history file, don't overwrite HISTSIZE=5000 # Number of commands to keep in memory HISTFILESIZE=10000 # Number of commands to keep in the history file # Save history after each command and reload it to make it available across terminals. # `history -a` appends the current session's history to HISTFILE. # `PROMPT_COMMAND="history -a; ${PROMPT_COMMAND}"` ensures this happens before each prompt. # Rely on histappend for merging on shell exit. PROMPT_COMMAND="history -a; ${PROMPT_COMMAND}" # 3. XDG directories export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}" # Ensure critical XDG directories exist mkdir -p "$XDG_CONFIG_HOME" "$XDG_CACHE_HOME" "$XDG_DATA_HOME" # Append Flatpak XDG data dirs to the system default XDG_DATA_DIRS _FLATPAK_USER_DATA_DIR="$XDG_DATA_HOME/flatpak/exports/share" _FLATPAK_SYSTEM_DATA_DIR="/var/lib/flatpak/exports/share" _SYSTEM_XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}" export XDG_DATA_DIRS="${_FLATPAK_USER_DATA_DIR}:${_FLATPAK_SYSTEM_DATA_DIR}:${_SYSTEM_XDG_DATA_DIRS}" # Clean up temporary variables unset _FLATPAK_USER_DATA_DIR _FLATPAK_SYSTEM_DATA_DIR _SYSTEM_XDG_DATA_DIRS # XDG_RUNTIME_DIR is critical and typically set by pam_systemd. # If it's not set, it indicates a problem with the system's session management (e.g., pam_systemd). # Do not attempt to set it manually to a /tmp path here as it can cause issues. if [ -z "$XDG_RUNTIME_DIR" ]; then # Log an error or warning if preferred, but avoid setting a non-standard fallback # echo "Warning: XDG_RUNTIME_DIR is not set. User services may not function correctly." >&2 : # No action, rely on system setup else export XDG_RUNTIME_DIR # Ensure it's exported if set by pam_systemd fi # 4. PATH updates export GOPATH="$HOME/go" _add_to_path_if_missing() { local dir_to_add="$1" local prepend="$2" # "prepend" or "append" if [ -d "$dir_to_add" ]; then case ":$PATH:" in *":$dir_to_add:"*) :;; # Already in PATH *) if [ "$prepend" = "prepend" ]; then PATH="$dir_to_add:$PATH" # Prepend for higher priority else PATH="$PATH:$dir_to_add" # Append fi ;; esac fi } _add_to_path_if_missing "/usr/local/go/bin" "prepend" # Go system binaries _add_to_path_if_missing "$GOPATH/bin" "prepend" # User-installed Go binaries _add_to_path_if_missing "$HOME/.local/bin" "prepend" # User-local pip installs, etc. # Rust path is handled by sourcing .cargo/env, which also prepends. unset _add_to_path_if_missing export PATH # 5. Rust environment [ -f "$HOME/.cargo/env" ] && source "$HOME/.cargo/env" # 6. Bash completion if ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then source /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then source /etc/bash_completion fi fi # 7. SSH agent: Prioritize systemd-user, then GNOME Keyring if in desktop session # This logic determines which SSH_AUTH_SOCK to use. # Path for the systemd user ssh-agent socket _SYSTEMD_SSH_AGENT_SOCK="$XDG_RUNTIME_DIR/ssh-agent.sock" if [ -n "$XDG_RUNTIME_DIR" ] && [ -S "$_SYSTEMD_SSH_AGENT_SOCK" ]; then # systemd user agent socket exists, use it. export SSH_AUTH_SOCK="$_SYSTEMD_SSH_AGENT_SOCK" elif [ -n "$DESKTOP_SESSION" ] && command -v gnome-keyring-daemon >/dev/null; then # No systemd user agent socket found (or XDG_RUNTIME_DIR not set), # but in a desktop session. Attempt to use/start GNOME Keyring. # GNOME Keyring might already be running via its own systemd user service or XDG autostart. # This eval will set SSH_AUTH_SOCK if gnome-keyring-daemon starts/is running and manages SSH. eval "$(gnome-keyring-daemon --start --components=secrets,ssh)" export SSH_AUTH_SOCK # Ensure it's exported from eval fi unset _SYSTEMD_SSH_AGENT_SOCK # Attempt to add default SSH key (id_rsa) if an agent is running and has no keys. if command -v ssh-add >/dev/null; then if ! ssh-add -l &>/dev/null; then # Check if agent has ANY keys if [ -n "${SSH_AUTH_SOCK}" ] && [ -S "${SSH_AUTH_SOCK}" ] && [ -f "$HOME/.ssh/id_rsa" ]; then # Agent seems to be running (socket exists), but no keys listed. Add id_rsa. # Suppress errors (e.g., passphrase needed but no tty, or key already added by another mechanism). ssh-add "$HOME/.ssh/id_rsa" 2>/dev/null || true fi fi fi # 9. Prompt if [[ "${EUID}" == "0" ]]; then # Root prompt PS1='\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] ' else # User prompt PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' fi # 10. Aliases (!!! REVIEW AND REPLACE PLACEHOLDERS !!!) alias ls='ls --color=auto -hF' # Added -h for human-readable sizes, -F for type indicators alias ll='ls -alFh' # Added -h alias la='ls -Ah' # Added -h alias l='ls -CFh' # Added -h alias grep='grep --color=auto' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' # Example ping alias (uses default system ping) alias p='ping -c 4 example.com' # Pings example.com 4 times # Swaks alias for email testing # !!! REPLACE with your actual email, app password, and possibly SMTP server !!! # For Gmail, you'll need an "App Password". See Google's help documentation. # alias Z='swaks -4 -tls -f you@gmail.com -t recipient@example.com -s smtp.gmail.com:587 -au you@gmail.com -ap YOUR_GMAIL_APP_PASSWORD -d' alias Z='echo "Swaks alias Z not configured. Edit ~/.bashrc with your email details and an App Password for services like Gmail."' # Git project aliases # !!! REPLACE 'REPO' with your actual repository directory name if different !!! # And ensure ~/projects/REPO is a git repository. PROJECTS_DIR="$HOME/projects" # Example: alias project1-pull='(cd "$PROJECTS_DIR/my-actual-project" && git pull) || echo "Failed to cd or pull in $PROJECTS_DIR/my-actual-project"' alias pullrepo='(cd "$PROJECTS_DIR/REPO" && git pull) || echo "Failed to cd to $PROJECTS_DIR/REPO or pull"' alias pushrepo='(cd "$PROJECTS_DIR/REPO" && git push) || echo "Failed to cd to $PROJECTS_DIR/REPO or push"' # Update system alias update='sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y && sudo apt clean && echo "System update process completed."' # Check for listening ports alias listports='sudo ss -tulnp' EOF

Key points about this revised .bashrc:

  • Placeholders in Aliases: Critical for Z (swaks) and pullrepo/pushrepo.
  • History: Uses PROMPT_COMMAND="history -a; ${PROMPT_COMMAND}" for immediate availability of commands in other terminals, with shopt -s histappend for merging on exit.
  • XDG Directories: Uses standard defaults if variables are unset. Avoids risky XDG_RUNTIME_DIR fallback.
  • PATH Management: Robustly adds paths, prepending for priority.
  • SSH Agent Logic: Clearly prioritizes the systemd-user agent. If its socket $XDG_RUNTIME_DIR/ssh-agent.sock exists, it’s used. Otherwise, if in a DESKTOP_SESSION, it attempts to use/start gnome-keyring-daemon. Then, it tries to add ~/.ssh/id_rsa if an agent is active but has no keys.
  • Prompt: Colored prompt, different for root and regular users.
  • Aliases: Minor improvements like -h for human-readable sizes in ls.

Apply .bashrc changes: For the current terminal session, source it:

source "$HOME/.bashrc"

New terminals will load it automatically.

#2.6. Configure systemd-user SSH Agent Service

This creates a service that automatically starts ssh-agent for the linaro user upon login.

Create the service file ~/.config/systemd/user/ssh-agent.service: (Ensure ~/.config/systemd/user exists and has 0700 permissions from step 2.1).

cat << 'EOF' > "$HOME/.config/systemd/user/ssh-agent.service" [Unit] Description=SSH Authentication Agent for User Session # This service should start early if it's going to be used. # .bashrc will connect to the socket if this service is running. # It doesn't need to be a hard requirement for default.target if SSH isn't always used # or if another agent (like GNOME Keyring) is preferred in some sessions. Documentation=man:ssh-agent(1) Before=default.target # Requires XDG_RUNTIME_DIR to be available and the user session to be set up. After=network.target systemd-user-sessions.service user@$(id -u).service [Service] Type=forking # The Environment variable defines the socket path for *this* ssh-agent instance. # %t expands to the XDG_RUNTIME_DIR path (e.g., /run/user/1000). Environment=SSH_AUTH_SOCK=%t/ssh-agent.sock # ssh-agent with -a creates the socket and forks into the background. ExecStart=/usr/bin/ssh-agent -a %t/ssh-agent.sock # Restart=always # Optional: uncomment if you want it to try restarting on failure. [Install] WantedBy=default.target EOF

Enable and start the service:

systemctl --user daemon-reload systemctl --user enable ssh-agent.service systemctl --user start ssh-agent.service # Or restart if it was already running: systemctl --user restart ssh-agent.service
  • What: ssh-agent.service defines how systemd manages ssh-agent for user linaro.
  • Why: Provides a reliable, auto-starting SSH agent managed by systemd, independent of graphical sessions (unless GNOME Keyring takes precedence as configured in .bashrc).
  • Verification (after starting):
    systemctl --user status ssh-agent.service # Look for "active (running)" ls -al "$XDG_RUNTIME_DIR/ssh-agent.sock" # Should show the socket file, e.g., srw------- 1 linaro linaro 0 May 8 12:34 /run/user/1000/ssh-agent.sock ssh-add -l # If the .bashrc logic has run and added the key: # Should list your ~/.ssh/id_rsa key or state "The agent has no identities." if .bashrc hasn't run yet in a new shell # or if the key requires a passphrase that hasn't been entered.

#Part 3: Verification Checklist

After completing all steps, and ideally after logging out and logging back in (or rebooting) to ensure all services and profile scripts are loaded correctly:

  1. Go Version:
    go version
    • Expected: go version goX.Y.Z linux/amd64 (your chosen version).
  2. Rust Version:
    rustc --version cargo --version
    • Expected: Shows versions like rustc x.y.z ... and cargo x.y.z ....
  3. Bash Login Shell & .bashrc Sourcing:
    bash --login -ic 'type ll && echo SSH_AUTH_SOCK is $SSH_AUTH_SOCK'
    • Expected:
      • ll is an alias for ls -alFh
      • SSH_AUTH_SOCK is /run/user/$(id -u linaro)/ssh-agent.sock (or a GNOME Keyring path if in a desktop session and it took over).
  4. SSH Agent Status:
    ssh-add -l
    • Expected: Lists your ~/.ssh/id_rsa key (e.g., 4096 SHA256:... linaro@hostname (RSA)).
    • If it says “The agent has no identities.” try opening a new terminal. If your key has a passphrase, the ssh-add in .bashrc (if the terminal is interactive and TTY is available) or the first attempt to use the key (e.g., ssh somehost) should prompt for it. Once entered, the agent remembers it for the session (or longer if integrated with GNOME Keyring and configured to do so).
  5. XDG_RUNTIME_DIR:
    echo "$XDG_RUNTIME_DIR" stat -c "Permissions: %a, Path: %n" "$XDG_RUNTIME_DIR"
    • Expected: A path like /run/user/1000 (where 1000 is linaro’s UID). Permissions should be 700 (drwx——). If empty or permissions are wrong, systemd-user services and other applications might fail. This is normally set up by pam_systemd.
  6. Aliases: Test your aliases:
    ll # Should list files with details p # Should attempt to ping example.com # Z # Test after configuring with your email details # pullrepo # Test after setting up ~/projects/REPO

#Part 4: Understanding Key Features and Use Cases

  • SSH Agent (systemd-user vs. GNOME Keyring):
    • Your setup prioritizes the systemd-user ssh-agent.service. The socket for this is $XDG_RUNTIME_DIR/ssh-agent.sock.
    • If this systemd agent socket isn’t found AND you log into a desktop environment (where DESKTOP_SESSION is set), the .bashrc allows gnome-keyring-daemon to be used for SSH agent functions. GNOME Keyring is often auto-started by the desktop environment (e.g., via its own systemd user service or XDG autostart) and can integrate well with desktop login, potentially unlocking your SSH key automatically.
    • The ssh-add ~/.ssh/id_rsa line in .bashrc attempts to add your default private key to whichever agent’s SSH_AUTH_SOCK is currently active.
  • Passwordless SSH Login:
    1. Generate your key pair (ssh-keygen - done).
    2. Ensure ssh-agent is running and has your key added (ssh-add -l to check - handled by .bashrc and systemd service).
    3. Copy your public key to the remote server: ssh-copy-id user@remote_host.
    4. Now ssh user@remote_host should log you in without a password (it uses the key from the agent). If your key has a passphrase, the agent will prompt for it once per session (or as configured) and then remember it.
  • Git over SSH:
    • Once your SSH agent is working with your key, Git operations (clone, pull, push) with SSH URLs (e.g., git@github.com:user/repo.git) will automatically use the keys from the agent.
  • Agent Forwarding:
    • Allows using your local SSH keys on a remote server to connect to another subsequent server, without your private key ever leaving your local machine.
    • To use: ssh -A user@intermediate_host. From intermediate_host, you can then ssh further_host.
    • Security Note: Only use agent forwarding (-A or ForwardAgent yes) with trusted intermediate hosts.
    • Configure per-host in ~/.ssh/config:
      Host my_intermediate_server HostName server.example.com User your_user ForwardAgent yes
  • Hardware Tokens (e.g., YubiKey for SSH):
    • GNOME Keyring might offer some integration for PKCS#11 devices if supported by your desktop environment.
    • For direct control, typically packages like opensc-pkcs11 are installed, and the SSH client is configured to use the hardware token via its PKCS#11 library (e.g., by setting PKCS11Provider in ~/.ssh/config or using ssh -I /path/to/lib.so). This is an advanced setup.
  • Flatpak Integration (XDG_DATA_DIRS):
    • Adding Flatpak’s exports/share directories to XDG_DATA_DIRS helps your shell and desktop environment discover application metadata (like .desktop files) for Flatpak applications.
  • swaks Alias (Z):
    • This alias is a template for sending test emails. You must configure it with your sender email, recipient, SMTP server details, and an App Password if using services like Gmail with 2-Step Verification.
URL: https://ib.bsb.br/bashrc