You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
10 KiB

# This file will be sourced by every interactive bash and, since it's sourced in ~/.bash_profile, also by login bashes.
# First, if there's a global bashrc, load it.
[ -f /etc/bashrc ] && . /etc/bashrc
# Some hosts have a FQDN as their $HOSTNAME. This sucks in prompts etc.
# Let's make sure that we have a version with _just_ the first part.
# Set a custom PATH by modifying the default one. However, keep a copy of the default one in order to not keep prefixing
# it when nesting shells etc.
[ -z "$MASTERPATH" ] && export MASTERPATH="$PATH"
export PATH="$HOME/bin:$HOME/neovim/bin:$HOME/tmux/bin:$HOME/bin/git-annex.linux:$HOME/.local/bin:$MASTERPATH:$HOME/node_modules/.bin:$HOME/.poetry/bin"
# Additional directories to scan for man pages.
# The trailing colon causes this path to be prepended to the default.
export MANPATH="$HOME/neovim/share/man:$HOME/tmux/share/man:$HOME/bin/git-annex.linux/usr/share/man:"
# If we have sway available...
if command -v sway &>/dev/null; then
# Ask Firefox to run in Wayland mode.
# Also, if this is tty1, start sway instead.
if [ "$(tty)" = '/dev/tty1' ]; then
exec sway
# If we're in Windows Terminal, advertise true-color support.
if [ -n "$WT_SESSION" ]; then
export COLORTERM='truecolor'
# Some tools parse this variable to find out whether the terminal's background
# color is light or dark, see for example `:h 'background'` in Vim. I don't
# use light-background terminals anywhere, so I think it's safe to set a dark
# background as the default, if the terminal doesn't specify anything else.
[ -z "$COLORFGBG" ] && export COLORFGBG='7;0'
# If we are in a terminal, tmux is available and we're not running from _inside_ tmux already, replace this shell with tmux.
# Except when ~/.notmux exists.
if [ ! -e "$HOME/.notmux" ] && [ -z "$TMUX" ] && [ -t 0 ] && command -v tmux &>/dev/null; then
# In tmux, all clients connected to a session share the same view on it. If you want to have different views in each
# client (for example every client being a new terminal emulator window in a GUI setup), you need to use tmux's
# "session groups" feature. However, in that setup (where a new session will be created for each terminal
# emulator window), closing or detaching these windows will leave behind leftover sessions in the group. Therefore
# I'll create the "base session" manually and then attach additional sessions and clients to it for each terminal.
# Session names are unique, if the base session already exists this will fail silently. Note that this failure could
# also mean that the session could not be created at all for some reason. I don't know why this should happen, so
# I'll consider it out of scope for now.
tmux new-session -d -t main -s main-base 2>/dev/null || true
# Now, actually attach to that session group using an auto-incrementing session name (by not specifying -s).
exec tmux new-session -t main
# Default umask is 0022, i.e. write permissions only for the user, not the group.
# Some OSes have different defaults; this defines a standard for all of my machines.
umask 0022
# If this shell is connected to a tty, disable software flow control.
# In other words, prevent accidentally hitting ^S from freezing the entire terminal.
[ -t 0 ] && stty -ixon 2>/dev/null
# Automatically change into directories (without `cd`).
# I've been using `failglob` too, but it breaks too many completion scripts.
shopt -s autocd
# Don't store lines starting with a space in the history, or lines identical to the one before.
# Store timestamps in history file, and display them as 'Mon 2020-06-01 23:42:05'.
HISTTIMEFORMAT='%a %Y-%m-%d %H:%M:%S '
# Configure my OpenPGP key ID.
export PGPID="$(awk '/^default-key / { print $2 }' < $HOME/.gnupg/gpg.conf 2>/dev/null)"
# If we're not running in WSL, ask GnuPG to do PIN entry in this terminal.
# This will probably need some extending once I'm using a GUI pinentry.
# TODO: Check whether this works for Wayland. Probably not.
if [ -z "$WSL_DISTRO_NAME" ]; then
export GPG_TTY="$(tty)"
# Unfortunately, when using gpg-agent for SSH authentication, setting $GPG_TTY isn't enough. You need to specify the
# correct tty to gpg-agent _globally_. Therefore I think it's of no use to set it automatically on each new terminal.
# Instead, this alias, to be used manually, will update the agent and make it use the terminal the alias is run in.
# Note that there seems to be no way to _retrieve_ that value again from the agent in order to check whether it has been
# set to a sensible value _at all_ (and run `thistty` automatically if not).
alias thistty='echo UPDATESTARTUPTTY | gpg-connect-agent'
# Use gpg-agent for SSH if no other mechanism (e.g. ssh -A) is configured.
# Also override gnome-keyring-daemon's SSH integration, if active.
[ -z "$SSH_AUTH_SOCK" -o "$SSH_AUTH_SOCK" != "${SSH_AUTH_SOCK%/keyring/*}" ] && command -v gpgconf >/dev/null 2>&1 && export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
# Export the local GPG "extra" socket to an environment variable so that I can
# use it in my SSH config's RemoteForward commands (for gpg-agent forwarding).
export GPG_EXTRA_SOCKET="$(gpgconf --list-dir agent-extra-socket)"
# When cloning .gnupg via git, it receives 0755 permissions by default. Fix those, else it keeps displaying a warning.
chmod go-rwx "$HOME/.gnupg"
# When connected via SSH, ask GnuPG to not auto-start an agent.
# Instead, the idea is to forward & use the agent on my local machine (or not have GPG at all).
if [ -n "$SSH_CONNECTION" ]; then
alias gpg='gpg --no-autostart'
# ls aliases.
# Arguments common to every ls alias. Only use `--color` if ls actually supports that parameter.
alias ls="ls -F$(ls --color=auto "$HOME" >/dev/null 2>&1 && printf ' %s' '--color=auto')"
# List all (a), long format (l, one per line) and a combination of both.
alias a='ls -a' l='ls -lh' la='l -a'
# List by time. Also some combinations for reversing and combining with -a.
alias lt='l -t' ltr='lt -r' lta='lt -a' lat='lta' ltar='lta -r' latr='ltar'
# List by size. Same combinations as above.
alias lz='l -S' lzr='lz -r' lza='lz -a' laz='lza' lzar='lza -r' lazr='lzar'
# Create a directory and then change into it. If multiple directories are supplied,
# change into the last one.
mcd() {
mkdir -p -- "$@" && cd "${!#}"
# ssh doesn't allow setting the TERM variable via SetEnv (in .ssh/config), see
# <>. However, some of the machines I'm
# connecting to don't have alacritty in their terminfo files. This is the
# workaround I came up with: Set TERM to xterm for the ssh command invocation.
ssh() {
case "$TERM" in
TERM=xterm-256color "$(type -P ssh)" "$@"
"$(type -P ssh)" "$@"
# I have a script that chooses the "best" editor available on the system.
export EDITOR="$HOME/bin/edit"
# I also have a script that chooses the "best" available terminal.
# i3-sensible-terminal will use this variable.
export TERMINAL="$HOME/bin/terminal"
# Talk English to me.
export LANG='en_US.UTF-8'
# Reloading .bashrc.
alias rc=". '$HOME/.bashrc'"
# For each Git alias defined in .gitconfig, create a corresponding shell alias, prefixed with `g`.
# For example, the Git alias `s` for `status` will be available as `git s`, but also as `gs`.
# This line, by design, doesn't throw errors when Git is not installed.
eval alias g='git' $(git config --global --get-regexp '^alias\.' 2>/dev/null | sed -e 's/^alias\.\([^ ]*\) .*$/g\1='"'g \1'/")
# git-annex aliases (starting with `nx`) should be available without the
# `g` prefix.
eval alias $(git config --global --get-regexp '^alias\.nx' 2>/dev/null | sed -e 's/^alias\.\([^ ]*\) .*$/\1='"'g \1'/")
# Editor.
alias e='edit'
alias erc="edit '$HOME/.bashrc'; rc"
alias egit="edit '$HOME/.gitconfig'; rc" # source bashrc since Git aliases could have been updated
alias evim="edit '$HOME/.vim/vimrc'"
n() {
edit -c "call notizen#EditNew(\"$*\")"
alias wordle='e -c Wordle'
# If an alias value ends in a space, the following word is alias-expanded, too.
# So, this will allow you to use your aliases even when passing them to sudo:
alias sudo='sudo '
# Fedora 33 comes with default aliases for `vi` and `vim` that will decide
# dynamically whether vi or Vim will be launched. However, in combination with
# my `alias sudo='sudo '` from above, `sudo vim` will no longer work. This is a
# workaround for that issue: I simply remove the aliases.
[ "$(type -t vi)" = 'alias' ] && unalias vi
[ "$(type -t vim)" = 'alias' ] && unalias vim
# Diagnostics.
alias 1='ping'
alias 8='ping'
# Some more aliases.
alias pdfwdiff='pdfdiff --word-diff=color'
# GnuPG and other things to set up when under WSL.
if grep -q Microsoft /proc/version 2>/dev/null; then
launch-wsl-gpg-agent() { tmux new-session -d -s wsl-gpg-agent >/dev/null 2>&1; }
kill-wsl-gpg-agent() { tmux kill-session -t wsl-gpg-agent; }
restart-wsl-gpg-agent() { kill-wsl-gpg-agent && sleep 2 && launch-wsl-gpg-agent; }
# I've tried symlinking the usual location to the wsl-ssh-pageant socket, didn't work. So let's change SSH_AUTH_SOCK instead.
export SSH_AUTH_SOCK="$(wslpath -a "$(cmd.exe /c echo %APPDATA% 2>/dev/null | tr -d '\r')")/gnupg/S.wsl-ssh-pageant"
# Set $BROWSER to something that can open web pages.
export BROWSER='powershell.exe -Command start'
# Allow skipping the 'sudo' prefix when running my wslmount script.
alias mnt="sudo WSLMOUNT_OPTIONS=fmask=0007,dmask=0007 $HOME/bin/wslmount"
# YubiKey Manager CLI application when under WSL.
[ -x '/mnt/c/Program Files/Yubico/YubiKey Manager/ykman.exe' ] && alias ykman='/mnt/c/Program\ Files/Yubico/YubiKey\ Manager/ykman.exe'
# (Un)locking my BitWarden vault and setting the session environment variable.
alias bwu='export BW_SESSION="$(bw unlock --raw)"'
alias bwl='bw lock'
# Salt aliases.
alias salt='sudo salt-call --local'
alias salt-apply='salt state.apply'
alias salt-grains='salt grains.items'
. "$HOME/.bash/prompt.bash"
# Source a local bashrc, if it exists.
[ -f "$HOME/.bashrc.local" ] && . "$HOME/.bashrc.local"