346 lines
10 KiB
Markdown
346 lines
10 KiB
Markdown
---
|
|
title: "Bashrc"
|
|
description: "Details about my shell configuration"
|
|
author: "Thurstylark"
|
|
date: 2021-09-25
|
|
draft: false
|
|
---
|
|
|
|
# Bashrc
|
|
|
|
Source: https://git.thurstylark.com/vcsh/bashrc.git
|
|
|
|
## Profile
|
|
|
|
Bash chooses which dotfile to source based on how it gets run. If starting from a login shell, `~/.bash_profile` will get sourced, but if there's not a command in there to source your `~/.bashrc`, you may find yourself having to `exec bash` after starting bash. This can be fixed by adding the following line to your `~/.bash_profile`:
|
|
|
|
```prettyprint
|
|
[ -f ~/.bashrc ]( -f ~/.bashrc .md) && . ~/.bashrc
|
|
```
|
|
|
|
I also use `~/.bash_profile` for setting numlock while in a tty:
|
|
|
|
```prettyprint
|
|
case $(tty) in /dev/tty[0-9]*)
|
|
setleds -D +num * (numlock for X is set in ~/.xinitrc)
|
|
;;
|
|
esac
|
|
```
|
|
|
|
The last thing of note in my `~/.bash_profile` is a warning:
|
|
|
|
```prettyprint
|
|
- Temporary fix for a systemd bug related to systemd --user timers that run on login
|
|
[ -z "$DBUS_SESSION_BUS_ADDRESS" ]( -z "$DBUS_SESSION_BUS_ADDRESS" .md) && printf "%bWARNING: \$DBUS_SESSION_BUS_ADDRESS is unset! %b\n" "$(tput bold)$(tput setab 1)" "$(tput sgr0)"
|
|
```
|
|
|
|
----
|
|
|
|
## Main bashrc
|
|
|
|
Things started getting a little too expansive, so I split off relevant sections into their own files. Now all my individual utilities have their own file, making troubleshooting and adding functionality much easier. You can find info for each file and what it does in its own section on this page.
|
|
|
|
### General config
|
|
|
|
I'm not going in to detail about every line, but I'll hilight the important parts. The rest should be documented in the script itself.
|
|
|
|
First off, if we're not running bash interactively, there's no use for any of the rest of this, so just skip it.
|
|
|
|
```prettyprint
|
|
- If not running interactively, don't do anything
|
|
[ $- != *i* ]( $- != *i* .md) && return
|
|
```
|
|
|
|
Another cool option is actually built in to bash: If you call for a directory without any command before it, just `cd` into that directory.
|
|
|
|
```prettyprint
|
|
- If a directory is given without any command, CD into it.
|
|
shopt -s autocd
|
|
```
|
|
|
|
This is where all the other utilities, aliases, and functions get pulled in. Anything in `~/.bashrc.d/` ending in `.sh` will get pulled in.
|
|
|
|
```prettyprint
|
|
for f in ~/.bashrc.d/*.sh; do source "$f"; done
|
|
```
|
|
|
|
This also removes the need for the local bashrc sourcing that I [had in this file previously](https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc?id=30c53ca7224b583ed5068038b697653810e3b94b#n45). If that functionality is needed, simply make a new script in `~/.bashrc.d/` and don't track it with `vcsh`.
|
|
|
|
Ordering can be done by adding numbers to the beginning of filenames. For example: `10-prompt.sh`. Currently, nothing that I use requires that kind of functionality.
|
|
|
|
----
|
|
|
|
## Prompt
|
|
|
|
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/prompt.sh
|
|
|
|
I originally built my prompt using http://bashrcgenerator.com and, while it's a nice tool for visually building a prompt, it has several limitations on what you're able to create with it. But more importantly to me, it generates a rediculously long string, defines and resets color for every single character, uses both a color and bold escape sequence to use light/bright colors, mixes raw escape sequences and subshells running tput, and as a result is utterly unreadable and unmaintainable.
|
|
|
|
So, I replaced it:
|
|
|
|
```prettyprint
|
|
promptsetup() {
|
|
- Color definitions for prompt
|
|
local fg_brightred='\[$(tput setaf 9)\]'
|
|
local fg_blue='\[$(tput setaf 4)\]'
|
|
local fg_magenta='\[$(tput setaf 13)\]'
|
|
local fg_cyan='\[$(tput setaf 6)\]'
|
|
local fg_brightcyan='\[$(tput setaf 14)\]'
|
|
local fg_green='\[$(tput setaf 2)\]'
|
|
local reset='\[$(tput sgr0)\]'
|
|
local hostname='\h'
|
|
local mixin
|
|
|
|
- [hh:mm][username@hostname pwd]$
|
|
|
|
- Remotely, hostname is red.
|
|
[ -n "$SSH_CLIENT" ] && hostname="${fg_brightred}\h${reset}"
|
|
|
|
- If in a python venv, add venv name in green.
|
|
[ -n "$VIRTUAL_ENV" ] && mixin=" ${fg_green}$(basename "$VIRTUAL_ENV")${reset}"
|
|
|
|
- If in a vcsh repo env, add repo name in magenta.
|
|
[ -n "$VCSH_REPO_NAME" ] && mixin=" ${fg_magenta}$VCSH_REPO_NAME${reset}"
|
|
|
|
PS1="${fg_blue}[\A]${fg_cyan}[${fg_brightcyan}\u${fg_cyan}@${hostname}${mixin} ${fg_cyan}\W]${reset}\$ "
|
|
}
|
|
|
|
promptsetup
|
|
```
|
|
|
|
I intentionally put everything in a function and call it immediately so I may use local vars for the color definitions. I didn't really want to leave them around just in case.
|
|
|
|
----
|
|
|
|
## Aliases
|
|
|
|
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/alias.sh
|
|
|
|
Most of these are just creature comforts and fairly self-explanitory:
|
|
|
|
```prettyprint
|
|
##* ALIASES ###
|
|
|
|
- Colorize all `ls` output:
|
|
alias ls='ls -AF --color=auto'
|
|
|
|
- Map "la" to `ls -la`
|
|
alias la='ls -laFh --color=auto'
|
|
|
|
- Colorize `grep` output
|
|
alias grep='grep --color=auto'
|
|
|
|
- Change layout of lsblk to include FSTYPE and remove MAJ:MIN, RM, and RO collumns.
|
|
alias lsblk='lsblk -o NAME,FSTYPE,SIZE,TYPE,MOUNTPOINT'
|
|
|
|
- Always use sudo when using nmap.
|
|
alias nmap='sudo -E nmap'
|
|
|
|
- Switch $TERM temporarily (for logging into machines that don't have tmux-256color terminfo)
|
|
alias screenterm='TERM=screen-256color'
|
|
```
|
|
|
|
----
|
|
|
|
## Colored man Pages
|
|
|
|
Some color changes in `man` are almost essential for readability for me, so here's how I achieve that:
|
|
|
|
```prettyprint
|
|
- Enables colored Man pages:
|
|
man() {
|
|
env LESS_TERMCAP_mb=$'\E[01;31m' \
|
|
LESS_TERMCAP_md=$'\E[01;38;5;74m' \
|
|
LESS_TERMCAP_me=$'\E[0m' \
|
|
LESS_TERMCAP_se=$'\E[0m' \
|
|
LESS_TERMCAP_so=$'\E[38;5;246m' \
|
|
LESS_TERMCAP_ue=$'\E[0m' \
|
|
LESS_TERMCAP_us=$'\E[04;38;5;146m' \
|
|
man "$@"
|
|
}
|
|
```
|
|
|
|
This can also be done for any similar program that uses `less` as its pager.
|
|
|
|
----
|
|
|
|
## Get Dell Service Tag
|
|
|
|
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/getdst.sh
|
|
|
|
I work with Dell machines a lot, and when dealing with hardware problems, it's nice to have the service tag handy. Lucky for me, the service tag is easily retrieveable using `dmidecode(1)`, so I made a function for it.
|
|
|
|
```prettyprint
|
|
getdst() {
|
|
if [ "$1" = "-l" ]( "$1" = "-l" .md); then
|
|
printf "http://www.dell.com/support/home/us/en/04/product-support/servicetag/%s/configuration\n" "$(getdst)"
|
|
else
|
|
sudo dmidecode -s system-serial-number
|
|
fi
|
|
}
|
|
```
|
|
|
|
As an added bonus, the `-l` option will print the url for that product's support page.
|
|
|
|
----
|
|
|
|
## Screenshot
|
|
|
|
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/shot.sh
|
|
|
|
This function wraps `maim(1)` and `fb(1)` to simplify my most used options. It uses maim to capture either the full screen, the active window, or a mouse selection to a file, or directly to a pastebin.
|
|
|
|
```prettyprint
|
|
shot() {
|
|
- Usage: shot XY
|
|
local destdir="$HOME/Pictures/screenshots"
|
|
local fname
|
|
local pb="fb"
|
|
local paste msgt msgd opts
|
|
fname="shot-$(date +%F-%T).png"
|
|
|
|
if [ -z "$1" ]; then
|
|
printf "
|
|
Usage: shot XY
|
|
X: Target
|
|
Y: Destination
|
|
|
|
Valid Targets:
|
|
w Active Window
|
|
a All displays
|
|
s Mouse Selection
|
|
|
|
Valid Destinations:
|
|
f Save to file (defined in function)
|
|
p Upload to a pastebin (defined in function)
|
|
"
|
|
return
|
|
fi
|
|
|
|
- X: What to capture
|
|
case ${1:0:1} in
|
|
- Active window
|
|
w) printf "Focus target window now...\n"
|
|
opts="-i $(xdotool getactivewindow)"
|
|
msgt="active window"
|
|
;;
|
|
- All
|
|
a) msgt="all displays"
|
|
;;
|
|
- Mouse selection
|
|
s) opts="-s --noopengl"
|
|
msgt="mouse selection"
|
|
;;
|
|
|
|
-) printf "Invalid target: %s\n" "${1:0:1}"
|
|
return
|
|
;;
|
|
esac
|
|
- Y: Where to put the result
|
|
case ${1:1:1} in
|
|
- Save to file
|
|
f) msgd="file: $destdir/$fname"
|
|
;;
|
|
- Post to a pastebin
|
|
p) destdir=$destdir/pasted
|
|
msgd="pastebin"
|
|
paste=1;;
|
|
|
|
-) printf "Invalid destination: %s\n" "${1:1:1}"
|
|
return
|
|
;;
|
|
esac
|
|
|
|
- Make sure destination directory will exist
|
|
[ ! -d "$destdir" ]( ! -d "$destdir" .md) && mkdir -p "$destdir"
|
|
local fpath="${destdir}/${fname}"
|
|
|
|
- If target is active window, give a 5 second countdown before running maim
|
|
[ "$msgt" = "active window" ]( "$msgt" = "active window" .md) && countdown 5
|
|
|
|
maim "$opts" "$fpath"
|
|
printf "Captured %s -> %s\n" "$msgt" "$msgd"
|
|
|
|
- If destination is a pastebin, do the needful
|
|
[ "$paste" ]( "$paste" .md) && $pb "$fpath"
|
|
}
|
|
```
|
|
|
|
This probably isn't the most robust solution, but it works pretty well. Patches welcome.
|
|
|
|
|
|
----
|
|
|
|
## Countdown
|
|
|
|
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/countdown.sh
|
|
|
|
Found this little function when I wanted to add functionality to `shot()`. It takes an integer as an argument, then counts down that number of seconds visually.
|
|
|
|
```prettyprint
|
|
countdown() {
|
|
if [ -z "$1" ]; then
|
|
printf "
|
|
countdown: Count down while printing progress on the terminal
|
|
|
|
Usage: countdown <seconds>
|
|
"
|
|
fi
|
|
local secs="$1"
|
|
while [ "$secs" -gt 0 ]; do
|
|
echo -ne "$secs\033[0K\r"
|
|
sleep 1
|
|
: $((secs--))
|
|
done
|
|
}
|
|
```
|
|
|
|
This probably isn't the sanest or safest solution to the problem, but it gets the job done. Patches welcome.
|
|
|
|
----
|
|
|
|
## FontFind
|
|
|
|
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/fontfind.sh
|
|
|
|
Sometimes you just need to figure out what font provides a specific character. This function provides that solution:
|
|
|
|
```prettyprint
|
|
fontfind() {
|
|
if [ ${#1} -gt 1 ]( -z $1 |); then
|
|
printf "E: only one character accepted"
|
|
fi
|
|
local glyph=$1
|
|
FC_DEBUG=4 pango-view -qt "$glyph" 2>&1 | awk -F \" '/family: / { m = $2 } END { print m }'
|
|
}
|
|
```
|
|
|
|
----
|
|
|
|
## Vactivate
|
|
|
|
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/vactivate.sh
|
|
|
|
I started needing more than one python virtualenv, and I wanted easy access to my own specific file structure. Additionally, I wanted the ability to deactivate the venv like I would exit a child shell. This is the solution that I came up with:
|
|
|
|
```prettyprint
|
|
vactivate() {
|
|
local path=~/.venv/$1
|
|
|
|
if [ ! -d $path ]( ! -d $path .md); then
|
|
python -m venv $path --prompt "venv: $1"
|
|
fi
|
|
source $path/bin/activate; bash; deactivate
|
|
}
|
|
```
|
|
|
|
A caveat to this is that the prompt modification that venv usually applies is not available using this method. If a prompt modification is desired, it needs to be taken care of elsewhere. I take care of it in my prompt setup detailed [here](https://wiki.thurstylark.com/Bashrc.html#Prompt).
|
|
|
|
----
|
|
|
|
## Weechat
|
|
|
|
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/weechat.sh
|
|
|
|
See: [Weechat](Weechat.md).
|