function cheat() {
curl cht.sh/$1
}
It queries the cht.sh cheatsheet of various Unix commands. 'cheat tar' prints: # To extract an uncompressed archive:
tar -xvf /path/to/foo.tar
# To create an uncompressed archive:
tar -cvf /path/to/foo.tar /path/to/foo/
# To extract a .gz archive:
tar -xzvf /path/to/foo.tgz
# To create a .gz archive:
tar -czvf /path/to/foo.tgz /path/to/foo/
# To list the content of an .gz archive:
tar -ztvf /path/to/foo.tgz
# To extract a .bz2 archive:
tar -xjvf /path/to/foo.tgz
# To create a .bz2 archive:
tar -cjvf /path/to/foo.tgz /path/to/foo/
# To extract a .tar in specified Directory:
tar -xvf /path/to/foo.tar -C /path/to/destination/
# To list the content of an .bz2 archive:
tar -jtvf /path/to/foo.tgz
# To create a .gz archive and exclude all jpg,gif,... from the tgz
tar czvf /path/to/foo.tgz --exclude=\*.{jpg,gif,png,wmv,flv,tar.gz,zip} /path/to/foo/
# To use parallel (multi-threaded) implementation of compression algorithms:
tar -z ... -> tar -Ipigz ...
tar -j ... -> tar -Ipbzip2 ...
tar -J ... -> tar -Ipixz ...
You do have to be online, but there are ways of downloading the directory of cheat sheets to use offline as well.Anyways, the only options for tar that I commonly use are "c", "x", and "t"; I will use other programs for decompression, and for extracting into a directory, will use cd.
"create ze vucking file"
tar xzvf
"extract ze vucking files"
atool --extract $*
That will unpack "anything", into a sub-directory if necessary. Something I use more than any other alias. function extract () {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xjf $1 ;;
*.tar.gz) tar xzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) unrar e $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xf $1 ;;
*.tbz2) tar xjf $1 ;;
*.tgz) tar xzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "'$1' cannot be extracted via extract()" ;;
esac
else
echo "'$1' is not a valid file"
fi
}
instead if [ ! -s "${cache_dir}"/"$1" ] ; then ... firefox --new-instance --profile $(mktemp -d)
which pops open a new instance of Firefox with a completely clean, temporary profile.Super useful for testing sites or add-ons without influencing (or being influenced by) by my normal browsing profile.
#!/bin/sh
PROFILEDIR=`mktemp -p /tmp -d tmp-fx-profile.XXXXXX.d`
mkdir -p $PROFILEDIR/extensions
cd ~/.mozilla/firefox/yvwc47i0.default/
cp extensions/* $PROFILEDIR/extensions/
cp addons.json extensions.json $PROFILEDIR/
cp -R browser-extension-data $PROFILEDIR/
cp cert_override.txt $PROFILEDIR/
#cp prefs.js $PROFILEDIR/
echo 'user_pref("devtools.selfxss.count", 10);' > $PROFILEDIR/prefs.js
cd -
firefox -profile $PROFILEDIR -no-remote -new-instance
rm -rf $PROFILEDIR
Created this as a script somewhere in my path. You'd need to change `cd ~/.mozilla/firefox/yvwc47i0.default/` to match what yours is.Not exactly a bash alias, but might be useful too: Since I often get bug reports for specific versions of firefox, i've set up a small script for downloading and starting a given firefox version: https://pastebin.com/t2PHxJqE
alias crontab='fuck you, <insert name of colleague here>'
Background:Everyone knows that in a [in]sane workplace, you ALWAYS have to lock your machine. So this particular new hire forgot to lock her machine and one of the seniors (senior prankster, I would say) jumped into her terminal and set a crontab to run EVERY MINUTE.
So she comes back (we pair program so they were actually pairing that day) and goes on with programming for a few seconds. Then she tells us to be quiet. We're all like "WTF?" She asks, "Do you hear some robotic voice saying something?"
At this point we're all trying to listen but to no avail. She thinks it's her machine (which was connected to a 27" monitor) and proceeds to max the volume. A few seconds later, the whole office hears a thundering robotic voice say "ASSHOLE".
Everyone laughs. From that point onwards, we all had shortcuts to lock our screens, and as an added "security" feature, we aliased our crontab to actually say "fuck you" to our senior prankster.
It took the victim so long to figure out what was causing it, that it made it so much funnier.
I would then set their .zshrc or whatever to end with
echo "sleep 0.1" >> ~/.zshrc
so that every time they opened as hell, it would take 100ms longer to run. It would usually take them up to 1-2 second of startup time to figure out what was wrong.Now my favourite part was that I edited the oh-my-zsh update script to actually echo the original echo line into their ~/.zshrc file, so that even if they figured out what was happening and were very vigilant with locking their laptop, it would happen again within the next 14 days. Loved that.
say 'fuck you, <insert name of colleague here>'
If you put the commands:
set undofile
set undodir=~/.vim/undodir
You get infinite undo in your files.Now when you go into a file, delete or add some text and close your terminal down, the next time you enter vim you can (re|un)do previous operations.
Has saved my ass more times than I care to mention over my career!
I understand why developers don't have it on by default in other text editors (space) but seeing as I don't fill my HDD with movies or games or any other large media like that, i've got all the space in the world.
if !isdirectory($HOME . "/.vim/undodir")
call mkdir($HOME . "/.vim/undodir", "p")
endif
set undofile
set undodir=~/.vim/undodir let s:undos = split(globpath(&undodir, '*'), "\n")
call filter(s:undos, 'getftime(v:val) < localtime() - (60 * 60 * 24 * 90)')
call map(s:undos, 'delete(v:val)') pycd () {
pushd `python -c "import os.path, $1; print(os.path.dirname($1.__file__))"`;
}
Example usage, with abbreviated $PWD shown after "»" and shell commands entered after "$" in this example session: » (~/repos/web)
$ pycd flask
» (~/./v/3/e/w/l/p/s/flask)
$ pwd
~/.pyenv/versions/web+site/lib/python3.6/site-packages/flask
» (~/./v/3/e/w/l/p/s/flask)
$ head app.py
# -*- coding: utf-8 -*-
"""
flask.app
~~~~~~~~~
This module implements the central WSGI application object.
:copyright: © 2010 by the Pallets team.
:license: BSD, see LICENSE for more details.
"""
» (~/./v/3/e/w/l/p/s/flask)
$ popd
~/repos/web ~
» (~/repos/web)
$
So, usually lets you explore the source code, at the command-line, for any Python libraries you have installed. # setting common options
alias cp='cp -iv'
alias mv='mv -iv'
alias rmdir='rmdir -v'
alias ln='ln -v'
alias ls='ls --color=auto --human-readable --group-directories-first --classify'
alias grep='grep --color=auto'
# shortcuts
alias e=vim
alias music=ncmpcpp
alias g='git status'
alias gp='git push'
# show pretty git diff
alias gitdiff='git difftool -y -x "colordiff -y -W $COLUMNS" | less -R'
# go to root git directory
alias cdgit='cd $(git rev-parse --show-toplevel)'
# view csv files in columns
alias csv='column -s, -t'
# activate python venv
alias v='source ./venv/bin/activate'
# show weather
alias weather='curl wttr.in/Manchester'
# get my calendar
alias c='gcalcli --calendar <redacted> --monday calw'
# alternate view of calendar
alias agenda='gcalcli --calendar <redacted> agenda `date --iso-8601`T08 `date --iso-8601`T15'
# rot13 some text
alias rot13="tr '[A-Za-z]' '[N-ZA-Mn-za-m]'"
# I always forget how to echo status code
alias exitcode='echo $?'
# make directory and enter it
mdc() { mkdir -p "$@" && cd "$@"; }
# create a file and make git track it
ga() { touch "$@" && git add "$@" }
# open a twitch stream in mpv
twitch() { livestreamer --player "mpv -" "http://twitch.tv/$@" best }
# set terminal window title
title() { print -Pn "\e]2;$@\a" }
# open a file with less or a directory with ls
l() { if [ -f "$1" ]; then less "$1"; else ls "${1:-`pwd`}"; fi }So instead of having to type `cd ~/Projects/someproject` you could just type `j some` and it'll end up there.
>cd ~/Projects/someproject
>wd add . some
From then on you can use `wd some` to warp to that dir.
[1]: https://github.com/kigster/warp-dir
# allow directory variables
shopt -s cdable_vars
# set a directory variable
export some=~/Projects/someproject
You can then say `cd some` from anywhere and end up in `~/Projects/someproject`.It creates a different history file from each shell session. Most of my shell history goes back about 3 years now. The downside is you can't up arrow or crtl R except for your current history, but you can use the histgrep function to search everything.
I keep meaning to make another processed file which would uniq the history without the datestamp and maybe hook into fzf, but this has been good enough for now.
# tricks from https://news.ycombinator.com/item?id=10162189
if [ ! -d ~/.history/$(date -u +%Y/%m/) ]; then
mkdir -p ~/.history/$(date -u +%Y/%m/)
fi
#cat .history/2016/09/* |sort -n| uniq
export HISTFILE="${HOME}/.history/$(date -u +%Y/%m/%d.%H. %M.%S)_${HOSTNAME}_$$"
export HISTSIZE=
export HISTCONTROL=ignoreboth
export HISTCONTROL=erasedups
export HISTTIMEFROMAT="%d/%m/%Y-%H:%M:%S"
#export PROMPT_COMMAND='history -a'
export HISTIGNORE='&:bg:fg:clear:ls:pwd:history:exit:make*:* --help:'
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
histgrep ()
{
grep -r "$@" ~/.history
history | grep "$@"
}export HISTTIMEFROMAT="%d/%m/%Y-%H:%M:%S"
should HISTTIMEFROMAT be HISTTIMEFORMAT ?
bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'
This one automatically lists the files in the current directory, but limits the number of lines. function cd {
builtin cd "${@}"
if [[ "$(stat -c "%b" .)" -lt "100" ]]
then
if [ "$( ls -C -w $COLUMNS | wc -l )" -gt 30 ] ; then
ls -C -w $COLUMNS --color=always | awk 'NR < 16 { print }; NR == 16 { print " (... snip ...)" }; { buffer[NR % 14] = $0 } END { for( i = NR + 1; i <= NR+14; i++ ) print buffer[i % 14] }'
else
ls
fi
fi
} alias s="git status"
alias d="git diff"
I prefer looking at this stuff in a terminal rather than an IDE. Reducing them to a single character just feels so good. Note: not a git alias like "git s", literally just the single character "s" in Bash itself.And coming in third:
alias ..="cd .."I also have `..`, but also `...` which maps to `cd ../..`
alias ..="cd .."
If you use zsh, typing a directory name changes to it automatically. It’s almost always a very delightful thing. alias h="cd -"
to go to the last directory I was in. Inspired by how you move the cursor to the left in vim. set autocd shopt -s autocd> autocd If set, a command name that is the name of a directory is executed as if it were the argument to the cd command. This option is only used by interactive shells
alias diff='diff2html -s side' alias ci='git commit'
alias co='git checkout'
alias d='git diff'
alias dc='git diff --cached'
alias l='git log --oneline --graph --all --decorate'
alias ru='git remote update'
alias s='git status' $ alias ..
..=up
$ type -f up
up () {
local tmp_path=''
for i in $(seq 1 ${1:-1})
do
tmp_path+='../'
done
cd "$tmp_path"
} export WORKSPACE="$HOME/workspace"
alias ws='cd $WORKSPACE && ls'
History related commands: alias h="fc -li 1" # like `history` but with dates
# Which commands do I use the most?
alias histstats="history | awk '{CMD[\$2]++;count++;}END { for (a in CMD)print CMD[a] \" \" CMD[a]/count*100 \"% \" a;}' | grep -v './' | column -c3 -s ' ' -t | sort -nr | nl | head -n10"
Golang: alias gopath='cd $GOPATH/src && tree -dL 3'
Git: # --no-pager is underrated
alias glnp="git --no-pager log --oneline -n30"
Misc: # Have I been pwned?
# usage: `hibp email@example.com`
hibp() {
curl -fsS "https://haveibeenpwned.com/api/v2/breachedaccount/$1" | jq -r 'sort_by(.BreachDate)[] | [.Title,.Domain,.BreachDate,.PwnCount] | @tsv' | column -t -s$'\t'
}
# Weather
alias weather='curl wttr.in/$CITY' # ============= #
# Bash-specific #
# ============= #
alias sudo="sudo --preserve-env"
# Up & down map to history search once a command has been started.
bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'
alias tmux="tmux attach || tmux new"
alias fuck='sudo "$SHELL" -c "$(history -p !!)"'
alias fucking="sudo"
# ========================================================= #
# GnuPG SSH Authentication #
# ========================================================= #
# - Install "gnupg2" and "scdaemon". #
# - Add "enable-ssh-support" to "~/.gnupg/gpg-agent.conf" #
# - Or copy existing config from this repository #
# - Find [A]uthentication keygrips "gpg -K --with-keygrip" #
# - Add appropriate keygrips to "~/.gnupg/sshcontrol" #
# ========================================================= #
which gpgconf 1>/dev/null 2>&1
if [ $? -eq 0 ]; then
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agent
fiOpen current OSX Finder directory in Terminal:
cdf () {
target=`osascript -e 'tell application "Finder" to if (count of Finder windows) > 0 then get POSIX path of (target of front Finder window as text)'`
if [ "$target" != "" ]
then
cd "$target"
pwd
else
echo 'No Finder window found' >&2
fi
} function path {
if [[ -d "$1" ]] ; then
if [[ -z "$PATH" ]] ; then
export PATH=$1
else
export PATH=$PATH:$1
fi
fi
}
export PATH=''
path ~/.homebrew/sbin
path ~/.homebrew/bin
path /usr/local/sbin
path /usr/local/bin
path /usr/sbin
path /usr/bin
path /sbin
path /bin
It simplifies the syntax.I also like to keep vim swaps/backups/history in a centralized place (.vimrc):
set directory=~/.vim/swaps " centralized swaps
set backupdir=~/.vim/backups " centralized backups
set undodir=~/.vim/undo " centralized undo history
I don't like leaving ~clutter in random folders.I also like to alias sl to ls :)
alias sl='ls'
Other than that, the least you have to configure the better.You can check my dotfiles here: https://github.com/krmbzds/dotfiles
function lie {
if [[ "$1" == "not" ]]
then
unset GIT_AUTHOR_DATE
unset GIT_COMMITTER_DATE
return 0
fi
export GIT_AUTHOR_DATE="$1"
export export GIT_COMMITTER_DATE="$1"
}
My employers don't quite need to know how much I procrastinated in that particular task :PSome of my favourite recent ones...
List most recently modified files from the current directory and any below it. Helps remind me what I was working with when I don't ssh into a box regularly :
alias changedfiles="find . -type f -print0 | xargs -0 stat --format '%Z :%z %n' | sort -nr | cut -d: -f2- | head -n 20"
[ Need to tweak that sometime for BSD find on MacOSX, but I use it primarily on Linux ]Before backing up from a Unix-typical filesystem to an ExFAT volume attached by USB, find problematic characters in filenames from the current directory and any below :
function badnames {
find . -name '*[?<>\\:*|\"]*'
}
A big favourite on volumes with deeply nested directory structures. My favourite technique for a quick directory find and switch.If you use FZF, this will show all directories (not files) from the current directory downwards. You can do an incremental fuzzy search by starting to type, and quickly change to that directory by pressing Enter when the desired one is highlighted.
function fd() {
local dir
dir=$(find ${1:-.} -path '*/\.*' -prune -o -type d -print 2> /dev/null | fzf +m) && cd "$dir"
}
Love that one. As 'fd' is right under the fingers on the home row, the directory search and switch can look like magic when used quickly as part of the workflow. alias fuck='sudo $(history -p !!)'
It runs the previous command as root.https://github.com/k0nserv/dotfiles/blob/7721559be40bba09cd8...
alias gs="g status"
alias glff="git pull --ff-only"
alias glffc="git pull origin \$(current_branch) --ff-only"
alias glc="git pull origin \$(current_branch)"
alias gpc="git push origin \$(current_branch)"
alias gpcfl="git push origin \$(current_branch) --force-with-lease"
function goops { git add -A "$@" && git commit --amend --no-edit && gpcfl }
alias gbr="git branch -r"
alias grm="git branch --merged | grep -v \"\*\" | xargs -n 1 git branch -d"
function mkb() {
git fetch && git checkout -b "$1" origin/master
}
`mkdataenv` is nice for spinning up a quick Jupyter environment for all data analysis needs.https://github.com/k0nserv/dotfiles/blob/7721559be40bba09cd8...
function mkdataenv() {
mkvirtualenv --python /usr/local/bin/python3 $1
workon $1
mkdir "$1"
cd $1
pip install pandas jupyter numpy matplotlib seaborn
pip freeze > requirements.txt
jupyter notebook
} alias.alias config --global --get-regexp ^alias
I really like blameconflict: alias.blameconflict blame -L '/^<<<</,/^>>>>/' g fp # git fetch --prune
...
g rb origin/master master # rebase
g co -
A lot of tab and very few keys in general when working with git.My favorite aliases in this context are
alias wow=git
alias such=git
alias many=git
alias awesome=git
alias much=git function gen_passwd () {
openssl rand 150 |\
tr -dc '[:graph:]' |\
cut -c 1-${1:-13}
}
The default password length is 13 characters but you can pass a different length parameter instead.Explanation:
* generate 150 pseudo-random bytes using openssl's rand
* discard non-printable characters
* cut to desired length
Note that it will only use the ASCII character set, if you prefer a solution that also uses german umlauts (öäüÖÄÜß) or something more exotic like emoji in your passwords you're on your own.
tr -d iIlLOo0 env LC_CTYPE=C tr .. cd() {
# Set the current directory to the 0th history item
cd_history[0]=$PWD
if [[ $1 == -h ]]; then
for i in ${!cd_history[@]}; do
echo $i: "${cd_history[$i]}"
done
return
elif [[ $1 =~ ^-[0-9]+ ]]; then
builtin cd "${cd_history[${1//-}]}" || # Remove the argument's dash
return
else
builtin cd "$@" || return # Bail if cd fails
fi
# cd_history = ["", $OLDPWD, cd_history[1:]]
cd_history=("" "$OLDPWD" "${cd_history[@]:1:${#cd_history[@]}}")
}
Other than that, I doubt there's much that would be generally useful to anyone. cd() { if [[ -n "$2" && "$1" != "--" ]]; then builtin cd "${PWD/"$1"/"$2"}"; else builtin cd "$@"; fi; };
It's niche functionality, but super useful when you hit its niche: user@machine:/usr/src/linux-kbuild-4.9/scripts/mod$ cd 4.9 4.8
user@machine:/usr/src/linux-kbuild-4.8/scripts/mod$
I'll leave combining these two as an exercise for the reader. # shares history between tabs with prompt_command
HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups
_bash_history_sync() {
builtin history -a #1 appends command to histfile
HISTFILESIZE=$HISTSIZE #2 sets max size
builtin history -c #3 clears current session history
builtin history -r #4 reads the updated histfile and makes that the current history
}
history() { #5 overrides build in history to sync it before display
_bash_history_sync
builtin history "$@"
}
PROMPT_COMMAND=_bash_history_sync
Sometimes I forget the name of git branches I've worked on lately. This displays them with dates, most recent at the bottom: git_branch_dates() {
git for-each-ref --sort=authordate --format '%(authordate:iso) %(align:left,25)%(refname:short)%(end) %(subject)' refs/heads
}
Because I hate typing: # for rails migrations and keeping test updated
alias migrate="rake db:migrate && RAILS_ENV=test rake db:migrate"
Something I should use more to track things I've done lately - this opens up vim at the end of a file in your home dir called did.txt, appends the date and puts cursor at the last line: # didfile setup
alias did="vim +'normal Go' +'r!date' ~/did.txt"
Because sometimes you want to sudo an alias: # trailing space in value expands aliases that come after, see: http://www.linuxcommand.org/lc3_man_pages/aliash.html
alias sudo='sudo '
And displaying the git branch in the prompt: # this gets the git branch to display when I cd into a git repo
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h:\[\033[33;1m\]\w\[\033[m\]\[\033[32m\]\$(parse_git_branch)\[\033[00m\]\$ "
Because I often want to check recent files: alias llth='ls -hFlat | head'It's early and I'm lazy... will this always parse the branch upon entering any git directory?
function remac {
sudo /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -z
sudo ifconfig en0 ether $(openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//')
sudo networksetup -detectnewhardware
echo $(ifconfig en0 | grep ether)
}
Explanation: https://jezenthomas.com/free-internet-on-trains/Also, when I need to share a code snippet I pipe it to this:
alias ix="curl -F 'f:1=<-' ix.io"
Oh, and perhaps the most important part of my .vimrc: https://github.com/jezen/dotfiles/blob/master/.vimrc#L160 for i in ${HOME}/.bash.d/*.sh
do
if [ -r ${i} ] ; then
. ${i}
fi
done
And drop some custom scripts in ${HOME}/.bash.d/
like alias.sh, env.sh(my common .bash.d scripts are saved in a git repository)
Unless you're him!
The main include:
https://github.com/skx/dotfiles/blob/master/.bashrc
The actual dotfiles:
https://github.com/skx/dotfiles/
(People usually copy the literate emacs configuration ..)
pathadd() {
newelement=${1%/}
if [ -d "$1" ] && ! echo "$PATH" | grep -E -q "(^|:)$newelement($|:)" ; then
if [ "$2" = "after" ] ; then
PATH="$PATH:$newelement"
else
PATH="$newelement:$PATH"
fi
fi
}
pathrm() {
PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
} alias getmp3="youtube-dl -x --audio-format mp3 "
usage getmp3 https://www.youtube.com/watch?v=<id-of-some-nice-tune>
(You'll need to to `pip install youtube_dl` first and probably have `ffmpeg` installed too) cls="clear; ls"
It harkens back to DOS. Clearing the screen followed by ls happens surprisingly often, if not just to start things in "clean slate". I'm quite fond of it.My core work is alway around ~10 directories, which are mostly code packages. As soon as I start working on a project/team, I create aliases for directories. They take the form:
alias agg="cd /ws/ProjectName/src/PackageName/ &&
echo -n -e '\033]0;PackageName\007' &&
tab-color-devil-blue"
The first part of course navigates to the directory. The second part sets the tabName of my iTerm to the package name. The last part sets the background color of the tab to something unique for the package. This makes it easy to spot the right tab when I have like 10 iTerm tabs open.In case you want to see the definition of the last part:
set_tab_color() {
echo -ne "\033]6;1;bg;red;brightness;$1\a"
echo -ne "\033]6;1;bg;green;brightness;$2\a"
echo -ne "\033]6;1;bg;blue;brightness;$3\a"
}
tab-color-devil-blue() { set_tab_color 34 112 147 }
Tested only in iTerm.Here is the code I had https://gist.github.com/jontelang/c6317bf14c527d2a89f1efd5d0... and I put this straight into my .bash_profile and it runs automatically when the shell starts.
alias search='set -f;search';search() { find . ${2:+-name "$2"} -type f -print0 | xargs -0 grep --color=auto "$1"; }
Recursively searches the files in the current directory for string matches. You can optionally provide a second glob argument to restrict what files to search. This is basically a dumber version of ack-grep, but I wrote it before I learned about ack. fixup = "!f() { TARGET=\"$(git rev-parse \"$1\")\"; shift; git commit --fixup=\"$TARGET\" \"$@\" && git -c core.editor=true rebase --interactive --autostash --autosquash \"$TARGET^\"; }; f"
in = "!f() { case \"x$1\" in x-*|x) branch=;; *) branch=\"$1\"; shift;; esac; git glog \"$branch..$branch@{upstream}\" \"$@\"; }; f"
out = "!f() { case \"x$1\" in x-*|x) branch=;; *) branch=\"$1\"; shift;; esac; git glog \"$branch@{upstream}..$branch\" \"$@\"; }; f"
My most recent addition to my shell profile (a couple of weeks ago) enhances ts from the moreutils package. ts provides timestamps (relative to process execution or absolute) at the start of each line of stdout. My enhancement makes it cover stderr as well, so that stdout lines get a green timestamp and stderr lines get a red timestamp. Due to how interlacing works, and the fact that I commonly pair this with concurrency in the form of `make -j8`, it’s not perfect (can end up with a line possessing both green and red timestamps, and then none on the next line), but it’s still really helpful. I just need to get round to adding something to it to make programs still colour their own output. `script` can do that, I think.It’s currently this shell function:
ts-fancy() {
((("$@" 2>&1 1>&3 3>&-) | ts -s "^[[91m[%H:%M:%.S]^[[m") 3>&1 1>&2) | ts -s "^[[92m[%H:%M:%.S]^[[m"
}
(Each ^[ shown there is a literal ␛.) ts-fancy was the temporary name I gave it at first, haven’t renamed it to anything more permanent yet, so it’ll probably stay that way forever.Usage, `ts-fancy make -j8 --keep-going` and things like that. It’s proving really helpful when figuring out what’s slow in something that verbosely logs, and also in highlighting error output mixed in with normal output.
This exercise made me wish for a smarter terminal that kept track of timestamps and whether output went to stdout or stderr itself (at the character level, even, to resolve the problems of this line-based approach). I shouldn’t have to do this, and you know how often you think after the fact that it’d be nice to have timestamps?
It really seems very useful to have timestamps for every line of output.
I have tried to approximate this in the past, by setting my bash prompt to be:
export PS1='\[\e[00;37m\]$?\[\e[0m\]\[\033[1;32m\]\[\033[1;32m\][\t]\[\033[1;41m\]\u\[\033[1;41m\]@\[\033[1;41m\]\h:\[\033[0m\] \[\033[1;32m\]\w\[\033[0m\] \$ '
... which shows the previous command exit code, the current time (with second resolution) and the ordinary stuff like username host and working dir, so it looks somewhat like: 0[21:20:18]delian66@mypc: ~/Work $ slow_command
....
0[21:22:19]delian66@mypc: ~/Work $① I didn’t like an overly-long prompt. On my own machine I already exclude username and hostname, so it’s just `~/Work$ `. (Sometimes PWD gets a bit long, but generally not too much.)
② It was fairly rare that I actually cared about such a timestamp in any way—if I did, it was normally about time taken, and so I could pipe the program through `time` (this was before I discovered `ts` when figuring “someone must have made a program to do this” a couple of weeks ago when preparing to optimise a build process at work), or execute `date; …; date`.
③ Such a timestamp is only written when the prompt is output, rather than when the program is executed (there may be a sane way to have it work otherwise—I didn’t investigate in any way thoroughly—but my initial thoughts suggested any hacky attempt to move the cursor after the fact would interact badly with commands that cause the command line to span multiple lines). This made it useless for well over 90% of the cases when I might have benefited from it (retroactive timing of the duration of a command, rather than at what o’clock I… probably did something).
I return to the desire for a very mildly intelligent terminal that notes when characters were written to screen when not in raw mode, for optional viewing.
It just spawns the actual command in a sub process, but may be the output may be more ordered than that of a pipe of ts commands.
# Show Disk Use of subdirectories, sort by size
alias duss="sudo du -d 1 -h | sort -hr | egrep -v ^0"
# Cheatsheet autogenerated from i3 configuration file
alias i3cheatsheet="egrep ^bind ~/.i3/config | cut -d ' ' -f 2- | sed 's/ /\t/' | column -ts $'\t' | pr -2 -w 145 -t | less"
# Show mount information in a nice format
alias mountt="mount | column -t | sort"
# Show remaining dirty bytes while coping to a file, very useful in XFCE not sure in other enviroments
alias watchdirty="watch grep -e Dirty: -e Writeback: /proc/meminfo"
# Bookmark directories ej. "bm a" "go a" etc
go() { eval dir=\$$1; cd "$dir"; }
bm() { eval $1=$(pwd); echo "`set | egrep ^[a-z]+=\/`" > ~/.bookmarks; }
test -f ~/.bookmarks && source ~/.bookmarks
# I use this one all the time, combined find+grep, f.e. fgr "Class" "*.cpp" "-l" (2nd and 3rd parameters optional"
function fgr {
NAM=""
GREPTYPE="-i -H"
if [ -n "$1" ]; then
test -n "$2" && NAM="-name \"$2\""
test -n "$3" && GREPTYPE=$3
CMMD="find . $NAM -not -path '*/\.*' -exec egrep --colour=auto $GREPTYPE \"$1\" {} + 2>/dev/null"
>&2 echo -e "Running: $CMMD\n"
sh -c "$CMMD"
echo ""
else
echo -e "Expected: fgr <search> [file filter] [grep opt]\n"
fi
} CDPATH=./:~/:~/Documents/:[...]
I often grep/ag stuff only to think afterwards that I should have done that from Vim, so I have this to rerun the previous command and feed its output to Vim's quickfix: vimq() {
vim -q <($(fc -nl -1))
}
Speaking of Vim, this one lets me open an arbitrary file from the current project in Vim without having to glob: vimf() {
vim +find\ **/*$1
}
Create a directory and cd to it: mkcd() {
mkdir -p "$*"
cd "$*"
}
It's not in my .bash_profile but I use this little command all over the place to get my IP address (and I need my IP address a lot): #!/usr/bin/env sh
SYSTEM=$(\uname | \tr /a-z/ /A-Z/ | \cut -c-5)
# MacOS
if [ "$SYSTEM" = "DARWI" ]; then
\ifconfig | \sed '/vboxnet/{N;N;d;}' | \grep 'inet ' | \grep -v '127.0.0.1' | \awk '{print $2}' | \tr '\n' '-' | \sed 's/-.*//' | \tr -d '\n'
\exit 0
fi
# Linux
if [ "$SYSTEM" = "LINUX" ]; then
\ip route get 1 | \awk '{print $NF}' | \tr -d '\n'
\exit 0
fi
# MINGW/CYGWIN on Windows
if [ "$SYSTEM" = "MINGW" -o "$SYSTEM" = "CYGWI" ]; then
\ipconfig | \grep 'IPv4' | \awk '{print $NF}' | \tr -d '\n'
\exit 0
fi # misc
alias mount="mount | column -t"
alias ports="netstat -tulanp"
alias vmstat="vmstat -w"
alias ed="ed -p '>>> '"
# genpass
function genpass() { head -c 500 /dev/urandom | tr -dc a-z0-9A-Z | head -c $1; echo; }
# git stuff
alias gitpretty="git log --graph --oneline --decorate --all"
alias gitprettyall="git log --oneline --decorate --all -- graph --stat"
alias gfiles="git show --pretty='' --name-only $1"
alias gitstat="git log --stat"
alias gitchangelog="git log --oneline --no-merges ${1}..HEAD"
alias gittopcontrib="git shortlog -ns"
alias gitdiff="git difftool $1"I've also been using trash-cli [1] for years with `rm` aliased to `trash-put`. It's saved me a handful of times when I've carelessly `rm`d something I shouldn't have.
[0] https://github.com/junegunn/fzf
[1] https://github.com/andreafrancia/trash-cli - Command Line Interface to FreeDesktop.org Trash.
alias YOLO='aurman -Syyu --noedit --noconfirm'
I've tried several different, SimpleNote, KeepNote, EverNote... and so on. I have come to a conclusion, that using the default iOS note app is enough for me. Using paper notes while @lectures and rewriting them sometimes to Notes. I'm also using another method of note taking, which I prefer more, but which is not always accessible on the go. I stumbled upon a script here and modified it a little. (changed vim to nano and added some other):
#! /bin/bash
fpath=$HOME/notes.md
if [ "$1" == "cat" ]; then
cat "$fpath"
exit 0
elif [ "$1" == "rg" ]; then
rg "$2" "$fpath"
elif [ "$1" == "nano" ]; then
nano "$fpath"
elif [ "$1" == "--help" ]; then
printf 'Commands: \n-----------------------------------------------\n
$ notes \n
$ notes --help\t\t--\tdisplay this help\n
$ notes date\t\t--\tadd date row to notes\n
$ notes <text>\t\t--\tadd new entry \n
$ notes cat\t\t--\tprint notes using cat\n
$ notes rg <pattern>\t--\tripgrep notes\n
Remember to use #tags (for easier grepping)!\n\n'
elif [ "$1" == "date" ]; then
{
echo ''
echo '# '"$(date +"%m-%d-%Y-%T")"
echo '-'
} >> "$fpath"
elif [ "$1" == "" ]; then
less +G "$fpath"
else
{
echo ''
echo "$@"
echo ''
} >>"$fpath"
fi
In short, writing $ notes prints out displays the notes and writing $ notes <text> appends a new line. This is extremely powerful because of it's simplicity and easy accessibility in terminal (where I spend most of the time anyway)From thread: Ask HN: Favorite note-taking software? https://news.ycombinator.com/item?id=17532094
di = diff
dc = diff --cached
ap = add -p
unstage = reset HEAD -p
discard = checkout -p
ci = commit -v
ca = commit -va
amend = commit -v --amend
reword = commit -v --amend --only
extend = commit -v --amend --no-edit
ri = rebase -i
rem = rebase master
rim = rebase -i master
red = rebase development
rid = rebase -i development
continue = rebase --continue
skip = rebase --skip
pu = push -v --progress
poof = push -v --progress --force-with-lease
pusu = -c push.default=current push -v --progress --set-upstream sd () {
if [ -f "$*" ]
then
cd "$(dirname "$*")"
else
cd "$*"
fi
}
Also cwd which is like pwd but it also copies the current path to your clipboard. cwd='pwd | tr -d "\n" | pbcopy && pwd' alias continue-branch='charm $(git diff master --name-only)' # Open all files changed in the current branch wrt master in PyCharm
function record-window {
recordmydesktop --windowid=$(wmctrl -l | grep $1 | awk '{print $1}') -o ~/Videos/$1_$(date +"%Y_%m_%d_%H_%M_%S").ogv
}
alias ping='grc ping'
alias ifconfig='grc ifconfig'
alias netstat='grc netstat'
These last three use the awesome 'grc' output colorizer for i in `ls ~/.ssh/keys|grep -v ".pub"|grep -v "id_dsa$"`; do
cmd="$i"ssh
func="function $cmd {"
func="$func ssh -i ~/.ssh/keys/$i \$*;"
func="$func }"
eval $func
done
}_dynamic_ssh_creator
I have so many SSH keys that I can't be arsed to maintain an SSH config - especially when my brain is faster at it. This allows me to type <keyname>ssh and just live my life.
ix [<path>]
and will sumbit the content of the supplied path, or stdin if no path is given.Here's function at said pastebin (http://ix.io/1yiG/sh), and in raw form below:
ix() {
curl=$(command -v curl)
[ -f "$HOME/.netrc" ] && curl="${curl} --netrc"
while getopts ":d:i:n:e:" opt; do
case "${opt}" in
d) ${curl} --request DELETE "ix.io/${OPTARG}"; return;;
i) curl="${curl} --request PUT"; id="${OPTARG}";;
n) curl="${curl} --form read:1=${OPTARG}";;
e) curl="${curl} --form ext:1=${OPTARG}";;
:) error "Expected argument: -${OPTARG}"; return 1;;
*) echo 'Usage: ix [-d ID] [-i ID] [-n N] [<options>]';
return;;
esac
done
shift $((OPTIND - 1))
unset -v OPTIND OPTERR
if [ -t 0 ]; then
filename="$1"; shift
if [ "$filename" ]; then
${curl} --form f:1=@"$filename" "${@}" "ix.io/${id}"
return
fi
echo "^C to cancel, ^D to send."
fi
${curl} --form f:1='<-' "${@}" "ix.io/${id}"
unset -v curl opt id filename
} $ loz QUERY
will give the password from the ~/.passwords flat text database, last password is valid one. $ lozinka
will ask for questions and enter it into ~/.passwordsI suggest chattr +a ~/.passwords so that file cannot be deleted, only appended.
function loz () {
PASSWORDS=~/.passwords;
if [[ "$1" ]]; then
/bin/grep -i --color=auto "$1" $PASSWORDS;
else
echo "No query given."
fi
}
function lozinka () {
passwords=~/.passwords
echo -n "Hostname:"; read hostname;
echo -n "Service:"; read service;
echo -n "Username:"; read username;
echo -n "Email:"; read email;
password=$(pwgen -n -n -n -s 20 1)
echo -n "Password (${password}):"; read password1;
if [[ $password1 ]]; then
password=$password1
fi
if [[ ( $username || $email ) && $password ]]; then
line=$(join_by : $hostname $service $username $email $password);
echo $line >> $passwords;
tail -n1 $passwords;
else
echo "Nothing recorded as there is no username or email";
fi
}# CD to the root of the current git project
alias ,,='git rev-parse --git-dir >/dev/null 2>&1 && cd `git rev-parse --show-toplevel` || echo "Not in git repo"'
# Put my MBP to sleep in X minutes sleep-in() {echo "Sleeping laptop in $1 minutes..." && sleep $((60 * $1)) && pmset sleepnow}
# Check CI status nicely using hub (hub.github.com) function ci {
unbuffer hub ci-status -v $1 | sed 's/https:.*//'
}
# Rerun the last git command with the suggestion it had alias yup='eval $(fc -ln -1 | sed "s/git/git -c \"help.autocorrect=-1\"/")'
# Look up directories for a Makefile and run it - I couldn't find a way to actually search up directories, so `detect` is my own binary that does that function make {
if detect Makefile > /dev/null 2>&1 ; then
LOCATION=$(detect Makefile)
echo "Makefile found at $LOCATION"
cd $LOCATION && /usr/bin/make $* && cd - >/dev/null
else
echo "Makefile not found"
fi
} set +H
export HISTIGNORE="&"
alias reset="printf '\033\143'"
alias ls="ls --color=never -p -D '%Y-%m-%d %H:%M'"
alias pmake="gmake -j30"
PS1="\[\e[0;32m\][\w]$\[\e[m\] "
history -w
history -c
I turn off history substitution (sometimes ! get into my program arguments and I don't like surprises), and start with no history on new terminals. I don't trust myself not to run an rm * from a previous session, open another terminal, and hit up one too many times.A little colorization of the terminal prompt, and spicing up of ls output (the colors actually give me trouble, and often I can't read the dark blue items at all.)
But most specifically, I adore the reset alias. Unlike clear, it isn't undone when you scroll up. The built-in reset command takes forever to run and does a bunch of things I don't want.
HISTIGNORE is my absolute favorite. It doesn't log your last command to history if it's the same as the one already there. I'll often run make multiple times to fix compilation errors, and with HISTIGNORE, the command to run the resulting binary is only ever two up keystrokes away.
alias gs="git status"
alias gall="git add ."
alias gm="git commit" PS1="\[\033[01;31m\]Node \`node --version\`: \[\033[01;32m\]\`pwd\` \`git status -sb 2> /dev/null | head -n 1\`\n\[\033[01;34m\]\`date +'%a, %B %-d, %-l:%M:%S%P'\` \[\033[01;31m\]\$ \[\033[00m\]"
Pruning branches both remote and locally are also very helpful to do in these alias/functions: function gitpruneremote {
git remote prune origin
}
function gitprunelocal {
git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -D
}
Git pulling in every repo: function gitpullall {
cd ~/yourCodeDir
find . -type d -depth 1 -exec git --git-dir={}/.git --work-tree=$PWD/{} pull \;
}
This one is simple, and was useful in my LAMP dev days, to tail apache logs with line breaks formatted: function tailerr() {
tail -f /path/to/errorlog | sed 's/\\n/\n/g'
} alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias d='docker'
alias up='docker stack up --with-registry-auth'
alias node='node --experimental-modules --experimental-repl-await --no-warnings'
alias net='netstat -tunl'
alias jurl='curl -sLH "Content-Type: application/json"'
alias sb='source ~/.bashrc'
rand() {
openssl rand -base64 ${1:-15} | tr '+/' '-_' | tr -d '[[:space:]]='
}
randomstring() { LC_CTYPE=C tr -dc '[:print:]' < /dev/urandom | dd bs="${1:-16}" count=1 2>/dev/null; echo; }
serv() { docker run --rm --name "nginx-${1:-8000}" -p "${1:-8000}:80" "${@:2}" -v $PWD:/usr/share/nginx/html:ro caub/nginx-dev; }
npmRegexp='^(i|init|install|link|list|ls|outdated|pack|prefix|prune|publish|r|rb|rebuild|restart|run|start|stop|test|tst|unpublish|up|update)$'
n() {
if [[ "$1" =~ $npmRegexp ]]; then
npm "$@"
else
npm run "$@"
fi
}alias ll="ls -l"
alias ..="cd .."
alias ...="cd ../.."
alias mdd='mkdir $(date -I)'
alias cdd='cd $(date -I)'
alias xt="xtermset -T "
alias dtail="dmesg|tail"
alias cdl="cd (ls -ltr1 | grep '^d' | tail -1 | awk '{print $9}');"
cd to last directory by date. np() {
PACKAGE_VERSION=$(node -p -e "require('./package.json').version")
SHORTVER="v$PACKAGE_VERSION"
LONGVER="Version $PACKAGE_VERSION"
echo $LONGVER
git tag -a "$SHORTVER" -m "$LONGVER" && git push --tags && npm publish
} node -p "require('./package.json').version"
no need for -e, or also just: jq -r .version package.jsonMaking 'cd' more explicit:
cd ( ) {
builtin cd "$@"
echo "$OLDPWD -> $PWD"
}
Up directory alias ..='cd ../'
This one I use to find bits in my favourite books/essays, which I have in folders in /books, under e.g. /books/Shakespeare/Macbeth, then search with 'book to be or' etc. book () {
# Find occurrences of words in texts. Put folders in ~/books, or soft links (ln -s)
# Displays only complete words found, not parts of words.
GREP_COLOR=red
grep -r -n -i --word-regexp --color -C 1 "$*" ./books/
echo `grep -r -i "$*" ./books/ | wc -l` occurrences of \"$*\" found, `grep -i -r --word-regexp "$*" ./books/ | wc -l` as a whole word.
}
'dlm' downloads mp4 file from URL in clipboard #!/bin/bash
#dlm - download mp4 from clipboard URL. usage: 'dlm myfile' downloads myfile.mp4
#with resume after 5 secs until finish.
fname=$(pbpaste)
echo "Download $fname as $1.mp4 : "
until curl -C - -kLo $1.mp4 "$fname"
do
sleep 5
done # branches that were touched lately
nb() {
git for-each-ref --sort=-committerdate refs/heads/ -- format='%(committerdate:short) %(authorname) %(refname:short)' | head -n 10
}
# squash!
squash() {
if [ -n "$1" ]; then
git reset --soft HEAD~$1 && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
fi
}
# open pr page on github for current branch
pr () {
local repo=`git remote -v | grep -m 1 "(push)" | sed -e "s/.*github.com[:/]\(.*\)\.git.*/\1/"`
local branch=`git name-rev --name-only HEAD`
echo "... creating pull request for branch \"$branch\" in \"$repo\""
open "https://github.com/$repo/pull/new/$branch?expand=1"
}
# check who uses port
port() {
lsof -i tcp:"$@"
}
# rebases local branch from origin /master and force pushes it
repush(){
git fetch origin master
git stash
git rebase origin/master
git push --force
git stash pop
} function my-accept-line() {
# check if the buffer does not contain any words
if [ ${#${(z)BUFFER}} -eq 0 ]; then
# put newline so that the output does not start next
# to the prompt
echo
# check if inside git repository
if git rev-parse --git-dir > /dev/null 2>&1 ; then
# if so, execute `git status'
git status
else
# else run `ls'
ls -l
fi
fi
# in any case run the `accept-line' widget
zle .accept-line
}
# create a widget from `my-accept-line' with the same name
zle -N accept-line my-accept-line
# rebind Enter, usually this is `^M'
bindkey '^M' accept-line
This replaces `enter` (empty command line), with either `ls` or `git status` if in a git repository.This beautifully works as expected, I never got any bug because of this (as this could be expected for low level aliasing), and it does exactly what I'd expect: get current status of the current folder.
Now typing `git status` elsewhere is such a pain!
ga () {
if test "$#" -eq 0
then
echo "No arguments (0_0)?"
elif test "$#" -eq 1
then
git add -u && git commit -m "$(echo $1 | sed 's/^./\U&\E/')"
else
git add ${@:1:$(( $# - 1 ))} && git commit -m "$(echo ${@:$#} | sed 's/^./\U&\E/')"
fi
}
Usage: # Add all modified files and capitalize the commit message
ga "fix typo in README"
# Add some files and treat last arg as commit message
ga main.rs point.rs "speedup by 10e9"fav
#!/bin/bash --
f0() {
echo 'select moz_bookmarks.title || '"'"' = '"'"' || url from moz_places, moz_bookmarks on moz_places.id = moz_bookmarks.fk where parent = 2;' | sqlite3 /home/user/.mozilla/firefox/twht79zd.default/places.sqlite
}
f1() {
firefox `echo 'select url from moz_places, moz_bookmarks on moz_places.id = moz_bookmarks.fk where moz_bookmarks.title = '"'$1'"';' | sqlite3 /home/user/.mozilla/firefox/twht79zd.default/places.sqlite`
}
f$# $1
wikipedia #!/bin/bash --
firefox 'http://en.wikipedia.org/wiki/Special:Search?search='`node -p 'escape(process.argv[1])' "$1"`
(Maybe there is a better way than calling Node.js to escape the URL)icanhazip
#!/bin/bash --
curl 'http://icanhazip.com/'
repeat #!/bin/bash --
X=$1
shift
for X in `seq 1 $X`; do "$@"; done #!/bin/bash --
curl 'http://ipinfo.io'
ipinfo is a lot more verbose. Depending on your needs...Ex result: $curl ipinfo.io { "ip": "XXX.XXX.XXX.XXX", "hostname": "XXX.XXX.XXX", "city": "XXX", "region": "XXX", "country": "US", "loc": "XXX,XXX, "postal": "XXX", "phone": "XXX", "org": "ASXXX XXX XXX XXX" }
alias rm='rm -i'
alias mv='mv -i'
alias cp='cp -v'
alias ls='ls --color=auto -Fh'
alias ll='ls -l'
alias lla='ls -la'
alias clean='rm -rfv *~ .*~ \#*\# .\#*\#'
alias j='jobs'
alias rm='rm -i'
alias cp='cp -v'
alias mv='mv -v'
Workspace management function workon () {
LOC="$1"
cd "${HOME}/work/$LOC"
tmux attach -dt "$LOC" || tmux new -s "$LOC"
}
Handle the git submodules nightmare (a little) more easily alias subupdate='git submodule init; git submodule sync; git submodule update --init --recursive;'
Colored prompt with git branch: PMT=" "; if [ $UID -eq 0 ];then PMT="# " ;else PMT="$ " ; fi
WHITE="\[\033[0m\]"
YELLOW="\[\033[0;33m\]"
GREEN="\[\033[0;32;40m\]"
BLUE="\[\033[1;34m\]"
export PS1="[$GREEN\u@\h $BLUE\W$WHITE:$YELLOW\$(git branch 2>/dev/null | grep '^*' | colrm 1 2)$WHITE]"$PMT
Run a quick web server alias simpleWebServer='python -m http.server 8888'
If you are using tmux, WSL, and ssh all together, you may sometimes need something like this (I always keep it in my bash_aliases and since never had color issues :) if [ "$TERM" == "screen" ]; then
export TERM="screen-256color"
fi function mk() {
mkdir -p $1 && cd &1
}
alias gpm='git pull master'
alias gcm='git checkout master'
alias grh='git reset --hard HEAD'
alias gs='git status'
alias gd='git diff'
alias h='history | grep' # Use like, "h ssh" to see all ssh in your history rcbash='~/.bashrc'
alias src="source $rcbash"
alias vrc="vim $rcbash"
alias vimo="vim -O" # vsplit files
And then, a little snippet which made my "bashrc" less repetitive when it comes to folder aliases. gr4_folderize() {
# creates aliases and variables for a path
#
# $1 = used abbreviation
# $2 = folder path
#
# gr4_folderize "esp32" "/srv/dd/esp32"
# creates aliases `cdesp32`, `lsesp32` and `diresp32` env
# ${param:?word} writes `word` to stdout when param is unset or null
local abbrev="${1:?No abbreviation alias.}"
local folder="${2:?No directory to folderize.}"
export dir${abbrev}="$folder"
which > /dev/null 2>&1 cd${abbrev} || alias cd${abbrev}="cd $folder"
which > /dev/null 2>&1 ls${abbrev} || alias lll${abbrev}o="lla $folder"
} ask_yes () {
read -r -p "$1 = Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
return 0 # true = 0
else
return 1 # false = 1
fi
}
Plus `countdown timer` to make user think about what he has done, before he does it. (Code is a mess cause i used some snippet then created another from it) countdown_str () {
# countdown "00:01:00" # = hh:mm:ss
IFS=:
set -- $*
secs=$(( ${1#0} * 3600 + ${2#0} * 60 + ${3#0} ))
while [ $secs -gt 0 ]
do
sleep 1 &
printf "\r%02d:%02d:%02d" $((secs/3600)) $(( (secs/60)%60)) $((secs%60))
secs=$(( $secs - 1 ))
wait
done
echo
}
countdown_5 () {
countdown 5 2>/dev/null
}
countdown () {
secs=${1:-"00"}
mins=${2:-"00"}
hours=${3:-"00"}
chars=$(printf "%02d:%02d:%02d" $hours $mins $secs)
echo "Countdown from $chars"
countdown_str $chars 2>/dev/null
}Eg. open a project with “Visual Studio Code” get latest version from git, reset db and run seeding. Then install dependencies and run dev server, while opening chrome at the right localhost address. I usually run the command walk away to get a drink or food and when I’m back everything is running so I can just start working!
So, I had this in my rc files for a while:
start() { nohup "$@" &> /dev/null &; }
After that, I replaced the function with the custom command from here: http://web.archive.org/web/20151221072546/https://felixmilea...I'd still like to have auto completion for this, though, but I never got around to learning about the ways to achieve that in bash and zsh.
Edit: Also, the one I probably use the most:
alias l="ls -ltrash"
although I've started to replace it with e() { exa -bghHliSa --color=always "$@" | bat; }
et() { exa -bghHliSTa --color=always "$@" | bat; }It turns out that bash has a PROMPT_COMMAND variable which gets called before writing out PS1, so I use this to write my own rprompt. The main idea is just to use tput to draw a thing on the right and restore the cursor position afterward.
As is, I have something like below right-justified at each prompt:
user@host:pwd (git-branch)
It even degrades nicely if horizontal space starts getting cramped. Actually, the code is (I believe) just posix shell, so I define relevant functions in .profile and have .bashrc and .mkshrc use them as appropriate. Since it's a bit long, here are some pastebins that should be drop-in workable:- profile: http://ix.io/1yiC/sh
- bashrc: http://ix.io/1yiA/bash
- mkshrc: http://ix.io/1yiB/ksh
There are a couple caveats. Bash clears the whole line when deleting characters, which causes the rprompt to be cleared as well. On the other hand, mksh works as expected. Also, if you enter really long commands into the prompt, they will eventually bump into and overwrite the rprompt, instead of clearing it wholesale. I've not found this too much of a problem though.
In the code above, the rprompt() function defines the actual contents of the prompt and performs the graceful degredation. The rprompt_draw() function does the actual drawing and prompt_draw() links these two together to be used by bash, mksh, etc.
Feel free to ask my any questions or hate on my code.
Useful information that is still not in your prompt:
- status of the last run command: $?
- number of jobs in the background, if any
I have this, with some colors thrown in:
PS1='$(if [ \j != "0" ] ; then echo "[\j]"; fi)$?\$ 'Basically, for the reasons you mention, I dislike having that info set in PS1, but I find it considerably less distracting when right-justified. Having it visible, though, makes it easy to ascertain the execution context of commands in the terminal history buffer.
The status of last run command I have on my PS1. If it exits 0, then it's just a simple
$
otherwise, it's: errno$
I do like your idea of showing current background jobs, but I find myself relying more on tmux windows than background jobs, so I suspect that number would be mostly constant for myself anyway.Sure! the idea is that background jobs are very rare, and their existence should be clearly indicated in the prompt (in bright red). Usually, there are zero jobs and the prompt is silent about that.
Copies the directory of the current git dir into the clipboard.
which pbcopy &> /dev/null
if [[ $? -eq 0 ]]; then
CLIPBOARD_COMMAND="pbcopy"
fi
which clip &> /dev/null
if [[ $? -eq 0 ]]; then
CLIPBOARD_COMMAND="clip"
fi
cpgitdir() {
GIT_DIR=`git remote show -n origin | grep "Fetch URL" | sed -e "s/ Fetch URL: //" | tr -d '\n'`
echo "Copying git dir to clipboard: $GIT_DIR"
echo $GIT_DIR | tr -d '\n' | $CLIPBOARD_COMMAND
}
Allows you to split your .bash_profile into multiple .bash_profile files for clarity if [[ -d ~/.bash_profile.d ]]; then
for file in `find ~/.bash_profile.d -type f`; do
source $file
done
fi
Simple calculator calc () {
bc -l <<< "$@"
} alias diff='diff2html -s side'
This requires the diff2html cli - https://diff2html.xyz/ - install with `npm install -g diff2html-cli` alias cleangopro="rm -rf /Volumes/GOPRO/DCIM/*"
alias mkdir="mkdir -pv"
alias ssh<proj>="ssh <user>@<ip>"
alias clearmail='sudo rm /var/mail/<user>'
alias flushcache='dscacheutil -flushcache && sudo killall -HUP mDNSResponder'
alias listenforpwd="sudo tcpdump port http or port ftp or port smtp or port imap or port pop3 or port telnet -lA | egrep -i -B5 'pass=|pwd=|log=|login=|user=|username=|pw=|passw=|passwd=|password=|pass:|user:|username:|password:|login:|pass |user '"
alias listenforuseragent="sudo tcpdump -vvAls0 | grep 'User-Agent:'"
alias listenforgetreq="sudo tcpdump -vvAls0 | grep 'GET'" Host reproserver
User remi
Hostname 128.122.217.96
IdentityFile ~/.ssh/id_rpz alias l='ls -GFla'I use these 3
alias ls='ls --color=auto --group-directories-first' # override
alias l='ls -hF'
alias ll='ls -hAlF'
alias lt='ls -clthF'
Also, incredibly useful: alias c='clear'
I type `l` and `c` all the time. Then I get on a different machine and `command not found`. mcd(){ mkdir "$1"; cd "$1"; }
alias vd='vim -d' # vimdiff
alias grep=egrep # https://github.com/rupa/z
source ~/z.sh
git helpers # update all git repos in subdirs
alias gitp="ls -d */ | xargs -P10 -I{} git -C {} pull"
# fetch updates for git repos in subdirs
alias gitf="ls -d */ | xargs -P10 -I{} git -C {} fetch --all"
selection of most commonly used git aliases ci = commit -m
cf = clean -fxd
cl = clone
co = checkout
cm = commit --amend --no-edit
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %Cblue<%an>%Creset' --abbrev-commit --date=relative --all -n 25
pf = push -f --follow-tags
rb = rebase master
st = status -sb alias·mongo='docker·run·-it·--rm·--network=host·mongo·mongo'
alias·aws='docker·run·-it·--rm·-e·AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID·-e·AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY·--network=host·mesosphere/aws-cli' # easier navigation
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
alias .....="cd ../../../.."
alias ~="cd ~"
# Get current public ip address
alias ip="dig +short myip.opendns.com @resolver1.opendns.com"
# Alias for summing a column
alias mksum="paste -sd+ - | bc"
# Export pbcopy / pbpaste to linux
if [[ "${OSTYPE}" == "linux"* ]]; then
alias pbcopy="xclip -selection clipboard"
alias pbpaste="xclip -selection clipboard -o"
fi
# create a new directory and enter it
function mkd() {
mkdir -p "$@" && cd "$_";
}
# plot stuff directly from the command line.
# Example: seq 100 | sed 's/.*/s(&)/' | bc -l | plot linecolor 2
# -> Generate 100 numbers, wrap it in s(<num>) and calc sin(<num>)
function plot() {
{ echo 'plot "-"' "$@"; cat; } | gnuplot -persist;
}
# wrapper for easy extraction of compressed files
function extract () {
if [ -f $1 ] ; then
case $1 in
*.tar.xz) tar xvJf $1 ;;
*.tar.bz2) tar xvjf $1 ;;
*.tar.gz) tar xvzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) unrar e $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xvf $1 ;;
*.tbz2) tar xvjf $1 ;;
*.tgz) tar xvzf $1 ;;
*.apk) unzip $1 ;;
*.epub) unzip $1 ;;
*.xpi) unzip $1 ;;
*.zip) unzip $1 ;;
*.war) unzip $1 ;;
*.jar) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "don't know how to extract '$1'..." ;;
esac
else
echo "'$1' is not a valid file!"
fi
}
[1] https://github.com/NewProggie/Dev-UtilsHow often do you use that and how often do you get it right? :-)
My cd related aliases are the following. Especially the .<number> is surprisingly useful, although most of the time I only use .2 and .3
alias ..='cd ../'
alias .1='cd ../'
alias .2='cd ../../'
alias .3='cd ../../../'
alias .4='cd ../../../../'
alias .5='cd ../../../../../'
# sometimes, the space gets swallowed
alias cd.='cd .'
alias cd..='cd ..'
But that gave me an idea for another useful directory changer: "go to project root".Project root definition could vary, although nowadays it is probably "go to the first directory upstream with a .git directory"
Edit: found this elsewhere in this discussion posted by jgresty https://news.ycombinator.com/item?id=18901834
# go to root git directory
alias cdgit='cd $(git rev-parse --show-toplevel)' alias ll='ls -l' $ cat ~/bin/docker
#!/bin/bash
if [ "$DOCKER_HOST" != "" ]
then
HOST_ARG="-H $DOCKER_HOST"
fi
/usr/bin/docker $HOST_ARG $@
$ cat ~/bin/docker-compose
#!/bin/bash
if [ "$DOCKER_HOST" != "" ]
then
HOST_ARG="-H $DOCKER_HOST"
fi
/usr/local/bin/docker-compose $HOST_ARG $@I found myself needing to use deeply nested tmux sessions a few times and navigating between nestings is a huge pain under a vanilla setup. Using some configuration trickery, I was able to hack in keys to "focus" between nesting levels. Here's a repo I have it sitting under:
https://github.com/xelxebar/tmux-addons/tree/master/nesting
The code should be relatively drop-in and the README not terrible.
I'd love to hear thoughts.
function search-messages () {
/usr/local/bin/mu find --clearlinks --format=links --linksdir=~/Maildir/search "$@" && mutt -f ~/Maildir/search
} function certchain() {
# Usage: certchain
# Display PKI chain-of-trust for a given domain
# GistID: https://gist.github.com/joshenders/cda916797665de69ebcd
if [[ "$#" -ne 1 ]]; then
echo "Usage: ${FUNCNAME} <ip|domain[:port]>"
return 1
fi
local host_port="$1"
if [[ "$1" != *:* ]]; then
local host_port="${1}:443"
fi
openssl s_client -connect "${host_port}" </dev/null 2>/dev/null | grep -E '\ (s|i):'
} alias u="cd .."
alias uu="cd ../.."
alias uuu="cd ../../.."
alias uuuu="cd ../../../.." # Up command, from stackoverflow. Takes optional number of
levels to cd ../
up(){
local d=""
limit=$1
for ((i=1 ; i <= limit ; i++))
do
d=$d/..
done
d=$(echo $d | sed 's/^\///')
if [ -z "$d" ]; then
d=..
fi
cd $d
} alias ..='cd ../'
alias ...='cd ../../'
alias ....='cd ../../../'
alias .....='cd ../../../../' alias ea='vim ~/.bash_aliases'
alias ear='source ~/.bashrc'
* i type 'ea' whenever i think a commands should aliased.* add new aliases
* exit dan type 'ear' to refresh the bashrc.
go for another productive terminale.
shopt -s checkwinsize
shopt -s autocd
To make life better to my taste alias tmux="tmux new -A -s root"
export HISTCONTROL=ignoredups
To distinguish between development, test and production environments by color (VERY userful) export PS1='[\[\e[1;91m\]\u\[\e[0m\]@\[\e[1;31m\]\H\[\e[0m\] \[\e[1;95m\]\w\[\e[0m\]]\\$ '
export PS1='[\[\e[1;92m\]\u\[\e[0m\]@\[\e[1;32m\]\H\[\e[0m\] \[\e[1;95m\]\w\[\e[0m\]]\\$ '
export PS1='[\[\e[1;93m\]\u\[\e[0m\]@\[\e[1;33m\]\H\[\e[0m\] \[\e[1;95m\]\w\[\e[0m\]]\\$ ' recent = for-each-ref --count=25 --sort=-committerdate refs/heads/ --format="%(refname:short)"
so `git recent` lists the last 25 branches, and then in .bashrc: alias co='select br in $(git recent); do git co $br; break; done'
alias coo='select br in $(git br -r|grep -v "("|grep -v HEAD|cut -c3-|sed "s/^origin.//"); do git co $br; break; done'
and now `co` gives me a menu of recent local branches to check out, and `coo` does the same for remotes on origin alias mirror='wget -m -r -np -p -k -E'
alias g_short_hash='git rev-parse --short --verify HEAD'
alias g_head_branch='echo "`git symbolic-ref HEAD 2> /dev/null | cut -b 12-`"'
alias g_branch_w_hash='echo "`git symbolic-ref HEAD 2> /dev/null | cut -b 12-`-`git log --pretty=format:\"%h\" -1`"'
On OS X: alias sleepnow="pmset sleepnow"
alias netstat_tanp="lsof -Pnl +M -i4 -i6"#Git Aliases alias gc="git checkout" alias gp="git pull" alias gp="git pull --rebase" alias gb="git branch" alias gs="git status" alias gd="git diff" alias gl="git log --oneline" alias gu="git ls-files --others --exclude-standard"
#HDFS Alias alias hls="hdfs dfs -ls" alias hcat="hdfs dfs -cat" alias hrm="hdfs dfs -rm" alias hrmf="hdfs dfs -rm -r -f" alias hmd="hdfs dfs -mkdir"
ggs -> git status
ggco -> git checkout
ggd -> git diff
ggap -> git add --patch $ video2webm 300k myvideo.mp4 othervideo.mpg third.mov
function video2webm () {
bitrate=$1;
shift;
for file in "$@";
do out=${file%.*}.webm;
ffmpeg -y -i "$file" -c:v libvpx-vp9 -b:v $bitrate -pass 1 -speed 4 -c:a libopus -f webm /dev/null && \
ffmpeg -i "$file" -c:v libvpx-vp9 -b:v $bitrate -pass 2 -speed 1 -c:a libopus "$out";
done;
} alias master='git checkout master'
alias f='git fetch --all'
alias s='git status --untracked-files=all'
# go to the last branch I worked on, excluding master and the current branch
alias lb='git checkout `git for-each-ref --sort=-committerdate refs/heads/ | grep -v refs/heads/master$ | grep -v \`git rev-parse --abbrev-ref HEAD\`| head -n1 | cut -d \/ -f 3-`'Stuff like:
alias @projectName="cd $project && alias java='/some/specific/version' && export SOME_VAR=value"
or
alias @untrustedWifi="tor && torbrowser && set up an SSH tunnel to access mail etc"
I can't really share the actual contents, because they depend on a boatload of scripts in my ~/bin dir and they're all pretty specific to my environment.
Nothing comes close to the amount of time I saved with this one.
best. alias. ever.
function convert-decimaltobinary(){
n="$1"
bit=""
while [ "$n" -gt 0 ]; do
bit="$(( n&1 ))$bit";
: $(( n >>= 1 ))
done
printf "%s\n" "$bit"
}
function convert-binarytodecimal(){
echo "$((2#$1))"
}
function convert-hextodecimal(){
echo $(( 16#$1 ))
} function mkcd() { mkdir -p "$@" && eval cd "\"\$$#\""; } function workspace_cd() {
cd $@ && [ -f ".bashworkspace" ] && source .bashworkspace
}
alias wscd="workspace_cd"
Each .bashworkspace file contains something like this: export GOPATH={PATH HERE}
export PATH=$GOPATH/bin:$PATH
export GHC_PACKAGE_PATH={PATH HERE} unameOut="$(uname -a)"
case "${unameOut}" in
*Microsoft*) machine="WSL";;
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN:${unameOut}"
esac
unset unameOut
PROMPT_COMMAND='echo -ne "\033]0;[${machine}] ${USER}@${HOSTNAME}: ${PWD}\007"'[0] https://gitlab.com/victor-engmark/fgit/blob/9575803b3bf277d5...
vi()
{
emacs -nw --eval '(and (switch-to-buffer "foobar") (setq viper-mode t) (setq viper-inhibit-startup-message t) (setq viper-expert-level 1) (viper-mode))' "$@"
}
alias vim=vi
alias vim.tiny=vi
alias vim.basic=vi echo 'Hello dude '
As an iOS dev, this one is super useful: alias cdd='rm -rf ~/Library/Developer/Xcode/DerivedData/* && echo "Cleared DerivedData/"'Have you ever done it by mistake?
# Pacman functions
function pacinstall () {
sudo pacman -S "$@"
}
function pacremove () {
sudo pacman -R "$@"
}
function paclist () {
sudo pacman -Ql "$1" | less
}
function pacsearch () {
sudo /usr/bin/pacsearch "$@" | less
}alias ia="open $1 -a /Applications/iA\ Writer\ Classic.app"
alias makepass="pwgen -s 30 | awk '{print $NF}' | pbcopy"
alias phplint="find . -name \".php\" -print0 | xargs -0 -n1 -P8 php -l"
alias quicklint="find . -name \".php\" -depth 1 -print0 | xargs -0 -n1 -P8 php -l"
alias loc="find . -name '*.php' | xargs wc -l"
alias myip='curl -s https://api.ipify.org'
Just prints out my current public IP address. I also have a bunch of others mentioned in this thread, and I've abbreviated a bunch of self-explanatory docker-compose commands, e.g. dcdown, dcup, dcrestart, dcpullup, etc curl ifconfig.me
is also easy to remember function gc() { grep -rnI "$@" * ;}
function gcA() { grep -rnI -A 5 "$@" * ;}
function gcB() { grep -rnI -B 5 "$@" * ;}
function gcC() { grep -rnI -C 5 "$@" * ;}
function gcf() { grep -rnIl "$@" * ;}
Just helper functions built on top of grepedit: Thank you both!
-n enables line numbers
-I (eye) ignores matches on binary files
-l (ell) lists the filenames of matching files only (overrides -n)
-A, -B, and -C specify how many lines of context after, before, or around the match to display.
"$@" adds any additional command line arguments passed to the functions.
* selects all the files and directories in the current directory.
So, without other arguments, the first four functions list matches with line numbers for all files (ignoring binary files) in the current directory and below, with 0 lines context (match only), 5 lines context after, 5 lines context before, and 5 lines context around the match respectively. The final function lists the filenames only and provides no context or line numbers.
alias c='cd'
alias cd='cd ..'
Yes, I am lazy. Yes it has saved me thousands of keystrokes alias today='vim ~/notes/$(TS="Europe/London" date +%Y-%m-%d).txt'The trash-cli utility has some quirks related to mounted drives but once you understand how to set up correctly, aliasing rm to trash can save you from losing files you've deleted by mistake.
alias.gerritpush=push origin HEAD:refs/for/develop
alias.fixlast=!git commit -a --fixup=HEAD && GIT_EDITOR=true git rebase -i --autosquash HEAD~2
alias.loglast=log -n 1 -p export MAKEFLAGS=-j`nproc`
make will automatically parallelize builds for the number of cores on the machine. It also breaks various things interestingly, particularly build systems which don't pay attention to correct dependences. complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" s $ age NAME YYYY-MM-DD
to get the age of anybody: function age () {
NAME="$1";
DATE="$2";
if [[ $1 && $2 ]]; then
AGE=$(psql -Stc "SELECT age(date('${DATE}'));");
echo $NAME: $AGE, was born on $DATE | sed 's/ mon / month /' | sed 's/ mons \| mons,/ months /';
else
echo "No name or date supplied";
fi
}
function child () {
age "My child" "2012-03-12";
} function ff {
find . -iname \*$1\*
}
alias gr='ack -i' COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
See the Bash FAQ for more info.alias seetsv="column -s $'\t' -t"
alias seecsv="column -s ',' -t"
1. It is easy to discover all customizations
via autocomplete
2. It is not going to clash
with existing functionality
# (Sort stuff by size, latest down, in a directory)
alias qqsize="ls -lSrh"
alias qqdate="ls -lrt"
# First 100 of largest files/directories in a folder
function qqlargest_files_100(){
du -a ./ | sort -n -r | head -n 100
}
# Archivate item
qq-tar-gz-it () {
tar -zcvf $2 $1;
}
# Convert video to a gif
function qq_convert_video_to_gif(){
ffmpeg -i $1 $1.gif
}
# Push to GitHub
function togithub__master(){
git add -A;
git commit -m $1;
git push github master;
}
# Symlink config file
# 1. Move dotfile to a config directory.
# 2. Strip the dot
# 3. Symlink that file back to its place
function qqsymlink_config_file(){
directory_for_dot_file=$2
name_of_dot_file=$1
basename_of_dotfile=$(basename $name_of_dot_file)
echo "Basename of dotfile: $basename_of_dotfile"
dot_file_with_striped_dot=${basename_of_dotfile:1}
new_file_path=$directory_for_dot_file/$dot_file_with_striped_dot
echo "Moving $name_of_dot_file to $new_file_path";
mv $name_of_dot_file $new_file_path;
echo "Symlinking file $new_file_path to $name_of_dot_file ";
ln -s $new_file_path $name_of_dot_file;
}
# Enable touchpad
function qq__touchpad_enable(){
xinput set-prop $(xinput | grep Touch | grep -Po 'id=\K[0-9]+') "Device Enabled" 1
}
# Set monitor highlighting
alias qq_set_higlighting_to_level_1_100="sudo xbacklight -set"
# Display wifi SSID's
alias qqwifi-spots="sudo iwlist scan | grep ESSID"
# Add wifi network
function qqadd-wifi-network(){
## add-wifi-network just_wifi mypassword
wpa_passphrase $1 $2 >> /etc/wpa_supplicant/wpa_supplicant.conf
}
# Various, misc
# Mirror (webcam)
alias mirror="vlc v4l2:///dev/video0"
# Stopwatch/countdown
function stopwatch(){
date1=`date +%s`;
while true; do
echo -ne "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r";
sleep 0.1
done
}
function countdown(){
date1=$((`date +%s` + $1));
while [ "$date1" -ge `date +%s` ]; do
echo -ne "$(date -u --date @$(($date1 - `date +%s`)) +%H:%M:%S)\r";
sleep 0.1
done
}
Some other stuff that I use daily and is too long to list here is: * an increment, deduplicating backup that takes
around $0.52 per month on BackBlaze and on the
external hard drive via one command.
(Shameless plug: https://github.com/MichaelLeachim/borg_backblaze_backup)
* Internet blocker. (https://github.com/MichaelLeachim/internet_block)
Edit, formatting.function qq-tar-gz-it () { tar -zcvf ${1}.tar.gz $1; }
Saves a step.
alias bzip2='pbzip2'
alias bunzip2='pbzip2 -d'
alias gzip='pigz'
alias gunzip='pigz -d'
alias xz='pixz'
alias tar='tar --use-compress-program=pbzip2'
alias tar='tar --use-compress-program=pigz'gpush(){ git add --all . && git commit -m $1 && git push origin $2 }
alias o=xdg-open
alias dus='du -sh * | sort -h'
alias mkae=makeexec env TMOUT=259200 bash
# Linux hard mode
set -e
The tab completion integration is especially nice. alias gap='git add -p' alias reload='exec $SHELL -l'Because it is important to centralize all your dotfiles.
Disclaimer: I’m a chezmoi user.
alias v="nvim"Speaking of, what's this vi thing people keep mentioning? :>
#~/.inputrc is for nerds who don't want 1000-line bashrcs
#C-w deletes previous word (by spaces) by default
#bind C-q to delete previous word-segment instead of "start(?) term output"
stty -ixon
bind '"\C-q": backward-kill-word'
#bind C-s to move cursor to previous [:space:] instead of "stop(?) term output"
bind -r '\C-s'
bind '"\C-s": shell-backward-word'
#bind C-d to go forword, not crush the shell
set -o ignoreeof
bind '"\C-d": shell-forward-word'
#miscellaneous useful inputrc binds
#bind shift-tab to 'see how the next autocomplete option would look on the cmd line'
bind '"\e[Z": menu-complete'
#don't make me hit tab twice to see multiple completion options
bind "set show-all-if-ambiguous on"
bind "set show-all-if-unmodified on"
#multi-complete shows filetypes by colors
bind "set colored-stats on"
#ellipsis at 3+ common characters with multi-complete
bind "set completion-prefix-display-length 3"
if [[ "$__os" == "mac" ]]; then
#tab complete is no longer case-sensitive? interesting...
bind "set completion-ignore-case on"
#tab complete is not -_ sensitive.
bind "set completion-map-case on"
fi
#vim mode is actually a super pain compared to emacs on the command line.
set -o emacs
#C-n/p now do double duty, so this is like the best of all 3 worlds? I'll take it
bind '"\C-p":history-search-backward'
bind '"\C-n":history-search-forward'
#makes aliases work with sudo
alias sudo='sudo '
#use sudo -i to become root and keep your bashrc & vimrc
alias -- -i='-E bash --rcfile $HOME/.bashrc'
#can't get it to work when becoming other users. sucks to suck.
alias apt-get='sudo apt-get'
alias systemctl='sudo systemctl'
alias sc='sudo systemctl'
alias scr='sudo systemctl restart'
alias firewall='sudo firewall-cmd'
alias fw='sudo firewall-cmd'
alias yum='sudo yum'
alias yumy='sudo yum install -y'
alias py='python'
# b/c sed needs i with an empty string on Mac to properly in-place
alias sd='sed -i"" -e'
#alias ugh = sudo !!
alias ugh='sudo $(history -p !!)'
# -a: dotfiles. -I: not those dotfiles. -C: color.
alias tree='tree -a -C -I ".git"'
#tries to force color: (G):BSD; (--color):GNU, adds / after dirs, * after execs, etc (F);
#and human readable sizes (h)
alias ls='ls --color -GFh'
alias la='ls --color -GFhla'
alias cd.='cd ../'
alias cd..='cd ../../'
alias cd...='cd ../../../'
alias cd....='cd ../../../../'
#is it running? sometimes you need all the args (i.e., for java processes) to fully grep
psg() {
ps -ef | grep -i $* | grep -v grep || \
ps -efwww | grep -i $* | grep -v grep
}
alias g.='grep '\''.'\'' -IrnHe'
alias f.='find . -name' alias scs='systemctl status'
alias jc='journalctl --unit'They work kind of like z/j, but you don't have to have been there before and it will constrain to the current tree.
down SUB1 SUB2[...] does a breadth-first search down-tree from your current location, and takes you to the first directory with all the given substrings in order in its path.
This differs from just wrapping basic find . -ipath, which does depth-first. That way, down libs lands you in ./src/libs instead of ./src/a_subcomponent/foo/bar/libs.
up SUB1 does the same, but moves you up the tree instead. I didn't do multiple substrings here because I never needed them--I mostly use them with down to anchor to a subtree (e.g., down a_sub libs if I wanted the above result).
Both are case-insensitive as written. Change ipath to path in down and grep -oi to grep -o in up to make them case sensitive instead.
They may or may not be symlink safe, and may or may not be spaces-in-paths safe. Neither is in play in my source bases.
Last note, these were originally written in fish (ask me for those versions if you want them) before I ported them to bash, so may not be examples of stunning bash code. They've been tested on bash 3.2 (Mac), 4.x, and 5.0.
function joinstr {
local IFS="$1"
shift;
echo "$*"
}
function down {
if [ -z "$1" ]; then
echo "Usage: down SUBSTR [SUBSTR...]"
return 1
fi
# foo bar baz becomes *foo*bar*baz*
local pathspec=( "$@" )
pathspec="*"$(joinstr "*" ${pathspec[@]})"*"
local depth=1
local dest=""
# iterative depth first traversal to simulate breadth-first
while true; do
# Anything at all at this depth?
local first_result=$(find . -mindepth "${depth}" -maxdepth "${depth}" -type d -print -quit)
if [ -z "${first_result}" ]; then
# nope, we're done
break
fi
# How about what we're looking for?
dest=$(find . -mindepth "${depth}" -maxdepth "${depth}" -ipath "${pathspec}" -type d -print -quit)
if [ -n "${dest}" ]; then
# found it!
break
fi
depth=$((${depth} + 1))
done
if [ -z "${dest}" ]; then
echo "down: could not find path matching ${pathspec}"
return 2
fi
echo "down: changing directory to ${dest}"
cd "${dest}"
}
function up {
if [ -z "$1" -o -n "$2" ]; then
echo "Usage: up SUBSTR"
return 1
fi
# look for substr starting at parent
local dest=$(echo ${PWD%/*} | grep -oi ".*$1[^/]*")
if [ -z "${dest}" ]; then
echo "up: could not find path matching *$1*"
return 2
fi
echo "up: changing directory to ${dest}"
cd "${dest}"
}## Make screencast or convert to yt
ffsc () {
vid_name="$HOME/Videos/Screencasts/screencast_$(date +'%y%m%d-%H%M%S')"
case $1 in
sc) ffmpeg -f x11grab -s 1920x1080 -i $DISPLAY -r 30 -f alsa -i default -preset ultrafast \
-c:v ffvhuff -c:a flac ${vid_name}.mkv
printf "${vid_name}.mkv" | xsel -i
echo
echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
echo "Output file name: ${vid_name}.mkv"
echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
echo
[ -e /tmp/ffsc.tmp ] && { rm /tmp/ffsc.tmp }
printf "${vid_name}.mkv" > /tmp/ffsc.tmp
;;
yt) ffmpeg -i $2 -c:v libx264 -crf 18 -preset slow -pix_fmt rgb24 -c:a copy ${2/scr/yt_scr}
yt_name=$(cat /tmp/ffsc.tmp)
printf "${yt_name/scr/yt_scr}" | xsel -i
echo
echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
echo "Output file name: ${yt_name/scr/yt_scr}"
echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
echo
;;
mini) ffmpeg -i $2 -strict -2 -s 1680x1050 -r 60 -c:v libx264 -b:v 164 -crf 22 -preset slow \
-pix_fmt yuv420p -c:a copy -an ${2/scr/mini_scr}
mini_name=${2/scr/mini_scr}
ffmpeg -i ${mini_name} -filter:v "setpts=0.5*PTS" -an ${mini_name/.mkv/.mp4}
rm ${mini_name}
printf "${mini_name/.mkv/.mp4}" | xsel -i
echo
echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
echo "Output file name: ${mini_name/.mkv/.mp4}"
echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
echo
;;
esac
}And another nice one I didn't see here..
# Python as a calculator
pc() { python -c "print($*)"; }
set incsearch
set hlsearch
set ts=4
set smartindent
set tags=./tags;/
# truncate the $PWD
function cut_pwd
{
newPWD="${PWD/#$HOME/\~}"
local pwdmaxlen=$((${COLUMNS:-80}/4))
if [ ${#newPWD} -gt $pwdmaxlen ]
then
newPWD=".+${newPWD: -$pwdmaxlen}"
fi
}
PROMPT_COMMAND=cut_pwd
PS1="\h:\${newPWD} \\$ "alias hadouken='sudo $(history -p !!)'
set -o vi
emacs-style line-editing set -o emacs