aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/README.md0
-rw-r--r--src/tools/awk.md126
-rw-r--r--src/tools/bash.md169
-rw-r--r--src/tools/emacs.md86
-rw-r--r--src/tools/fish.md185
-rw-r--r--src/tools/gdb.md162
-rw-r--r--src/tools/git.md130
-rw-r--r--src/tools/radare2.md27
-rw-r--r--src/tools/tmux.md110
-rw-r--r--src/tools/zsh.md125
10 files changed, 1120 insertions, 0 deletions
diff --git a/src/tools/README.md b/src/tools/README.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/tools/README.md
diff --git a/src/tools/awk.md b/src/tools/awk.md
new file mode 100644
index 0000000..38b0cb1
--- /dev/null
+++ b/src/tools/awk.md
@@ -0,0 +1,126 @@
+# awk(1)
+
+```markdown
+awk [opt] program [input]
+ -F <sepstr> field separator string (can be regex)
+ program awk program
+ input file or stdin if not file given
+```
+
+## Input processing
+
+Input is processed in two stages:
+1. Splitting input into a sequence of `records`.
+ By default split at `newline` character, but can be changed via the
+ builtin `RS` variable.
+2. Splitting a `record` into `fields`. By default strings without `whitespace`,
+ but can be changed via the builtin variable `FS` or command line option
+ `-F`.
+
+Fields are accessed as follows:
+- `$0` whole `record`
+- `$1` field one
+- `$2` field two
+- ...
+
+## Program
+
+An `awk` program is composed of pairs of the form:
+```markdown
+pattern { action }
+```
+The program is run against each `record` in the input stream. If a `pattern`
+matches a `record` the corresponding `action` is executed and can access the
+`fields`.
+
+```markdown
+INPUT
+ |
+ v
+record ----> ∀ pattern matched
+ | |
+ v v
+fields ----> run associated action
+```
+
+Any valid awk `expr` can be a `pattern`.
+
+### Special pattern
+
+awk provides two special patterns, `BEGIN` and `END`, which can be used
+multiple times. Actions with those patterns are **executed exactly once**.
+- `BEGIN` actions are run before processing the first record
+- `END` actions are run after processing the last record
+
+### Special variables
+
+- `RS` _record separator_: first char is the record separator, by default
+ <newline>
+- `FS` _field separator_: regex to split records into fields, by default
+ <space>
+- `NR` _number record_: number of current record
+
+### Special statements & functions
+
+- `printf "fmt", args...`
+
+ Print format string, args are comma separated.
+ - `%s` string
+ - `%d` decimal
+ - `%x` hex
+ - `%f` float
+
+ Width can be specified as `%Ns`, this reserves `N` chars for a string.
+ For floats one can use `%N.Mf`, `N` is the total number including `.` and
+ `M`.
+
+- `strftime("fmt")`
+
+ Print time stamp formatted by `fmt`.
+ - `%Y` full year (eg 2020)
+ - `%m` month (01-12)
+ - `%d` day (01-31)
+ - `%F` alias for `%Y-%m-%d`
+ - `%H` hour (00-23)
+ - `%M` minute (00-59)
+ - `%S` second (00-59)
+ - `%T` alias for `%H:%M:%S`
+
+
+## Examples
+
+### Filter records
+```bash
+awk 'NR%2 == 0 { print $0 }' <file>
+```
+The pattern `NR%2 == 0` matches every second record and the action `{ print $0 }`
+prints the whole record.
+
+### Capture in variables
+```bash
+# /proc/<pid>/status
+# Name: cat
+# ...
+# VmRSS: 516 kB
+# ...
+
+for f in /proc/*/status; do
+ cat $f | awk '
+ /^VmRSS/ { rss = $2/1024 }
+ /^Name/ { name = $2 }
+ END { printf "%16s %6d MB\n", name, rss }';
+done | sort -k2 -n
+```
+We capture values from `VmRSS` and `Name` into variables and print them at the
+`END` once processing all records is done.
+
+### Run shell command and capture output
+```bash
+cat /proc/1/status | awk '
+ /^Pid/ {
+ "ps --no-header -o user " $2 | getline user;
+ print user
+ }'
+```
+We build a `ps` command line and capture the first line of the processes output
+in the `user` variable and then print it.
diff --git a/src/tools/bash.md b/src/tools/bash.md
new file mode 100644
index 0000000..a4df7da
--- /dev/null
+++ b/src/tools/bash.md
@@ -0,0 +1,169 @@
+# bash(1)
+
+## Expansion
+
+### Generator
+
+```bash
+# generate sequence from n to m
+{n..m}
+# generate sequence from n to m step by s
+{n..m..s}
+
+# expand cartesian product
+{a,b}{c,d}
+```
+
+### Parameter
+```bash
+# default param
+bar=${foo:-some_val} # if $foo set, then bar=$foo else bar=some_val
+
+# check param set
+bar=${foo:?msg} # if $foo set, then bar=$foo else exit and print msg
+
+# indirect
+FOO=foo
+BAR=FOO
+bar=${!BAR} # deref value of BAR -> bar=$FOO
+
+# prefix
+${foo#prefix} # remove prefix when expanding $foo
+# suffix
+${foo%suffix} # remove suffix when expanding $foo
+
+# substitute
+${foo/pattern/string} # replace pattern with string when expanding foo
+# pattern starts with
+# '/' replace all occurences of pattern
+# '#' pattern match at beginning
+# '%' pattern match at end
+```
+
+> Note: `prefix`/`suffix`/`pattern` are expanded as [pathnames](#pathname).
+
+### Pathname
+
+```bash
+* match any string
+? match any single char
+\\ match backslash
+[abc] match any char of 'a' 'b' 'c'
+[a-z] match any char between 'a' - 'z'
+[^ab] negate, match all not 'a' 'b'
+[:class:] match any char in class, available:
+ alnum,alpha,ascii,blank,cntrl,digit,graph,lower,
+ print,punct,space,upper,word,xdigit
+```
+
+Wit `extglob` shell option enabled it is possible to have more powerful
+patterns. In the following `pattern-list` is one ore more patterns separated
+by `|` char.
+
+```bash
+?(pattern-list) matches zero or one occurrence of the given patterns
+*(pattern-list) matches zero or more occurrences of the given patterns
++(pattern-list) matches one or more occurrences of the given patterns
+@(pattern-list) matches one of the given patterns
+!(pattern-list) matches anything except one of the given patterns
+```
+> Note: `shopt -s extglob`/`shopt -u extglob` to enable/disable `extglob`
+> option.
+
+## I/O redirection
+
+> Note: The trick with bash I/O redirection is to interpret from left-to-right.
+
+```bash
+# stdout & stderr to file
+command >file 2>&1
+# equivalent
+command &>file
+
+# stderr to stdout & stdout to file
+command 2>&1 >file
+```
+
+### Explanation
+
+```bash
+j>&i
+```
+Duplicate `fd i` to `fd j`, making `j` a copy of `i`. See [dup2(2)][dup2].
+
+Example:
+```bash
+command 2>&1 >file
+```
+1. duplicate `fd 1` to `fd 2`, effectively redirecting `stderr` to `stdout`
+2. redirect `stdout` to `file`
+
+## Completion
+
+The `complete` builtin is used to interact with the completion system.
+```bash
+complete # print currently installed completion handler
+complete -F <func> <cmd> # install <func> as completion handler for <cmd>
+complete -r <cmd> # uninstall completion handler for <cmd>
+```
+
+Variables available in completion functions:
+```bash
+# in
+$1 # <cmd>
+$2 # current word
+$3 # privous word
+
+COMP_WORDS # array with current command line words
+COMP_CWORD # index into COMP_WORDS with current cursor position
+
+# out
+COMPREPLY # array with possible completions
+```
+
+The `compgen` builtin is used to generate possible matches by comparing `word`
+against words generated by `option`.
+```bash
+compgen [option] [word]
+
+# usefule options:
+# -W <list> specify list of possible completions
+# -d generate list with dirs
+# -f generate list with files
+# -u generate list with users
+# -e generate list with exported variables
+
+# compare "f" against words "foo" "foobar" "bar" and generate matches
+compgen -W "foo foobar bar" "f"
+
+# compare "hom" against file/dir names and generate matches
+compgen -d -f "hom"
+```
+
+### Example
+Skeleton to copy/paste for writing simple completions.
+
+Assume a program `foo` with the following interface:
+```bash
+foo -c green|red|blue -s low|high -f <file> -h
+```
+
+The completion handler could be implemented as follows:
+```bash
+function _foo() {
+ local curr=$2
+ local prev=$3
+
+ local opts="-c -s -f -h"
+ case $prev in
+ -c) COMPREPLY=( $(compgen -W "green red blue" -- $curr) );;
+ -s) COMPREPLY=( $(compgen -W "low high" -- $curr) );;
+ -f) COMPREPLY=( $(compgen -f -- $curr) );;
+ *) COMPREPLY=( $(compgen -W "$opts" -- $curr) );;
+ esac
+}
+
+complete -F _foo foo
+```
+
+[dup2]: http://man7.org/linux/man-pages/man2/dup.2.html
diff --git a/src/tools/emacs.md b/src/tools/emacs.md
new file mode 100644
index 0000000..b288fb1
--- /dev/null
+++ b/src/tools/emacs.md
@@ -0,0 +1,86 @@
+# emacs(1)
+
+## help
+```markdown
+ C-h ? list available help modes
+ C-h f describe function
+ C-h v describe variable
+ C-h c <KEY> print command bound to <KEY>
+ C-h k <KEY> describe command bound to <KEY>
+ C-h b list buffer local key-bindings
+ <kseq> C-h list possible key-bindings with <kseq>
+ eg C-x C-h -> list key-bindings beginning with C-x
+```
+
+## package manager
+```markdown
+ package-refresh-contents refresh package list
+ package-list-packages list available/installed packages
+```
+
+## window
+```markdown
+ C-x 0 kill focused window
+ C-x 1 kill all other windows
+ C-x 2 split horizontal
+ C-x 3 split vertical
+```
+
+## yank/paste
+```markdown
+ C-<SPACE> set start mark to select text
+ M-w copy selected text
+ C-w kill selected text
+ C-y paste selected text
+ M-y cycle through kill-ring
+```
+
+## block/rect
+```markdown
+ C-x <SPC> activate rectangle-mark-mode
+ M-x string-rectangle <RET> insert text in marked rect
+```
+
+## mass edit
+```makrdown
+ C-x h mark whole buffer (mark-whole-buffer)
+ M-x delete-matching-line <RET> delete lines matching regex
+ M-x % search & replace region (query-replace)
+ C-M-x % search & replace regex (query-replace-regexp)
+```
+
+## grep
+```markdown
+ M-x find-grep <RET> run find-grep result in *grep* buffer
+ n/p navigate next/previous match in *grep* buffer
+```
+
+## lisp mode
+```markdown
+ M-x lisp-interaction-mode activate lisp mode
+ C-M-x evaluate top expr under cursor
+ C-x C-e eval-last-sexp
+ C-u C-x C-e eval-last-sexp and prints result in current buffer
+```
+
+## narrow
+```markdown
+ C-x n n show only focused region (narrow)
+ C-x n w show whole buffer (wide)
+```
+
+## org
+```markdown
+ M-up/M-down re-arrange items in same hierarchy
+ M-left/M-right change item hierarchy
+ C-RET create new item below current
+ C-S-RET create new TODO item below current
+ S-left/S-right cycle TODO states
+```
+
+### org source
+```markdown
+ <s TAB generate a source block
+ C-c ' edit source block (in lang specific buffer)
+ C-c C-c eval source block
+```
diff --git a/src/tools/fish.md b/src/tools/fish.md
new file mode 100644
index 0000000..2cc763e
--- /dev/null
+++ b/src/tools/fish.md
@@ -0,0 +1,185 @@
+# fish(1)
+
+## Quick Info
+Fish initialization file `~/.config/fish/config.fish`
+
+Switch between different key bindings:
+- `fish_default_key_bindings` to use default key bindings
+- `fish_vi_key_bindings` to use vi key bindings
+
+## Variables
+Available scopes
+- `local` variable local to a block
+- `global` variable global to shell instance
+- `universal` variable universal to all shell instances + preserved across
+ shell restart
+
+### Set/Unset Variables
+```text
+set <name> [<values>]
+ -l local scope
+ -g global scope
+ -U universal scope
+ -e erase variable
+ -S show verbose info
+ -x export to ENV
+ -u unexport from ENV
+```
+
+### Lists
+In `fish` all variables are lists (start with index `1`, but lists can't
+contain lists.
+```text
+set foo a b c d
+
+echo $foo[1] # a
+echo $foo[-1] # d
+echo $foo[2..3] # b c
+echo $foo[1 3] # a c
+```
+
+`$` can be seen as dereference operator.
+```text
+set foo a; set a 1337
+echo $$foo # outputs 1337
+```
+
+Cartesian product.
+```text
+echo file.{h,cc}
+# file.h file.cc
+
+echo {a,b}{1,2}
+# a1 b1 b2
+```
+
+### Special Variables (Lists)
+```text
+$status # exit code of last command
+$pipestatus # list of exit codes of pipe chain
+
+$CMD_DURATION # runtime of last command in ms
+```
+
+#### `*PATH`
+Lists ending with `PATH` are automatically split at `:` when used and joined
+with `:` when exported to the environment.
+```text
+set -x BLA_PATH a:b:c:d
+echo $BLA_PATH # a b c d
+env | grep BLA_PATH # BLA_PATH=a:b:c:d
+```
+
+## Command Handling
+```text
+# sub-commands are not run in quotes
+echo "ls output: "(ls)
+```
+
+### I/O redirection
+```text
+# 'noclobber', fail if 'log' already exists
+echo foo >? log
+```
+
+## Control Flow
+### `if` / `else`
+```text
+if grep foo bar
+ # do sth
+else if grep foobar bar
+ # do sth else
+else
+ # do sth else
+end
+```
+
+### `switch`
+```text
+switch (echo foo)
+case 'foo*'
+ # do start with foo
+case bar dudel
+ # do bar and dudel
+case '*'
+ # do else
+end
+```
+
+### `while` Loop
+```text
+while true
+ echo foo
+end
+```
+
+### `for` Loop
+```text
+for f in (ls)
+ echo $f
+end
+```
+
+## Functions
+Function arguments are passed via `$argv` list.
+```text
+function fn_foo
+ echo $argv
+end
+```
+### Autoloading
+When running a command fish attempts to autoload a function. The shell looks
+for `<cmd>.fish` in the locations defined by `$fish_function_path` and loads
+the function lazily if found.
+
+This is the preferred way over monolithically defining all functions in a
+startup script.
+
+### Helper
+```text
+functions # list al functions
+functions foo # describe function 'foo'
+functions -e foo # erase function 'foo'
+
+funced foo # edit function 'foo'
+ # '-e vim' to edit in vim
+```
+
+## Prompt
+The prompt is defined by the output of the `fish_prompt` function.
+```text
+function fish_prompt
+ set -l cmd_ret
+ echo "> "(pwd) $cmd_ret" "
+end
+```
+> Use `set_color` to manipulate terminal colors.
+
+
+## Useful Builtins
+```text
+# history
+history search <str> # search history for <str>
+history merge # merge histories from fish sessions
+
+# list
+count $var # count elements in list
+
+# string
+string split SEP STRING
+```
+
+## Keymaps
+```text
+ Shift-Tab ........... tab-completion with search
+ Alt-Up / Alt-Down ... search history with token under the cursor
+ Alt-l ............... list content of dir under cursor
+ Alt-p ............... append '2>&1 | less;' to current cmdline
+```
+
+## Debug
+```text
+ status print-stack-trace .. prints function stacktrace (can be used in scripts)
+ breakpoint ................ halt script execution and gives shell (C-d | exit
+ to continue)
+```
diff --git a/src/tools/gdb.md b/src/tools/gdb.md
new file mode 100644
index 0000000..7a43ca1
--- /dev/null
+++ b/src/tools/gdb.md
@@ -0,0 +1,162 @@
+# gdb(1)
+
+# CLI
+
+```markdown
+ gdb [opts] [prg [-c coredump | -p pid]]
+ gdb [opts] --args prg <prg-args>
+ opts:
+ -p <pid> attach to pid
+ -c <coredump> use <coredump>
+ -x <file> execute script <file> before prompt
+ -ex <cmd> execute command <cmd> before prompt
+ --tty <tty> set I/O tty for debugee
+```
+
+# Interactive usage
+
+```markdown
+ tty <tty>
+ Set <tty> as tty for debugee.
+ Make sure nobody reads from target tty, easiest is to spawn a shell
+ and run following in target tty:
+ > while true; do sleep 1024; done
+
+ set follow-fork-mode <child | parent>
+ Specify which process to follow when debuggee makes a fork(2)
+ syscall.
+
+ sharedlibrary [<regex>]
+ Load symbols of shared libs loaded by debugee. Optionally use <regex>
+ to filter libs for symbol loading.
+
+ break [-qualified] <sym> thread <tnum>
+ Set a breakpoint only for a specific thread.
+ -qualified: Tred <sym> as fully qualified symbol (quiet handy to set
+ breakpoints on C symbols in C++ contexts)
+
+ rbreak <regex>
+ Set breakpoints matching <regex>, where matching internally is done
+ on: .*<regex>.*
+
+ command [<bp_list>]
+ Define commands to run after breakpoint hit. If <bp_list> is not
+ specified attach command to last created breakpoint. Command block
+ terminated with 'end' token.
+
+ <bp_list>: Space separates list, eg 'command 2 5-8' to run command
+ for breakpoints: 2,5,6,7,8.
+
+ info functions [<regex>]
+ List functions matching <regex>. List all functions if no <regex>
+ provided.
+
+ info variables [<regex>]
+ List variables matching <regex>. List all variables if no <regex>
+ provided.
+
+ info handle [<signal>]
+ Print how to handle <signal>. If no <signal> specified print for all
+ signals.
+
+ handle <signal> <action>
+ Configure how gdb handles <signal> sent to debugee.
+ <action>:
+ stop/nostop Catch signal in gdb and break.
+ print/noprint Print message when gdb catches signal.
+ pass/nopass Pass signal down to debugee.
+
+ catch signal <signal>
+ Create a catchpoint for <signal>.
+```
+
+# User commands (macros)
+
+Gdb allows to create & document user commands as follows:
+```markdown
+ define <cmd>
+ # cmds
+ end
+
+ document <cmd>
+ # docu
+ end
+```
+
+To get all user commands or documentations one can use:
+```markdown
+ help user-defined
+ help <cmd>
+```
+
+# Hooks
+
+Gdb allows to create two types of command `hooks`
+- `hook-` will be run before `<cmd>`
+- `hookpost-` will be run after `<cmd>`
+```markdown
+ define hook-<cmd>
+ # cmds
+ end
+
+ define hookpost-<cmd>
+ # cmds
+ end
+```
+
+# Examples
+
+## Catch SIGSEGV and execute commands
+This creates a `catchpoint` for the `SIGSEGV` signal and attached the `command`
+to it.
+```markdown
+ catch signal SIGSEGV
+ command
+ bt
+ c
+ end
+```
+
+## Run `backtrace` on thread 1 (batch mode)
+```markdown
+ gdb --batch -ex 'thread 1' -ex 'bt' -p <pid>
+```
+
+## Script gdb for automating debugging sessions
+To script gdb add commands into a file and pass it to gdb via `-x`.
+For example create `run.gdb`:
+```markdown
+ set pagination off
+
+ break mmap
+ command
+ info reg rdi rsi rdx
+ bt
+ c
+ end
+
+ #initial drop
+ c
+```
+This script can be used as:
+```markdown
+ gdb --batch -x ./run.gdb -p <pid>
+```
+
+# Know Bugs
+
+## Workaround `command + finish` bug
+When using `finish` inside a `command` block, commands after `finish` are not
+executed. To workaround that bug one can create a wrapper function which calls
+`finish`.
+```markdown
+ define handler
+ bt
+ finish
+ info reg rax
+ end
+
+ command
+ handler
+ end
+```
diff --git a/src/tools/git.md b/src/tools/git.md
new file mode 100644
index 0000000..a4af0cf
--- /dev/null
+++ b/src/tools/git.md
@@ -0,0 +1,130 @@
+# git(1)
+
+## staging
+```markdown
+ git add -p [<file>] ............ partial staging (interactive)
+```
+
+## Remote
+```markdown
+ git remote -v .................. list remotes verbose (with URLs)
+ git remote show [-n] <remote> .. list info for <remote> (like remote HEAD,
+ remote branches, tracking mapping)
+```
+
+## Branching
+```markdown
+ git branch [-a] ................ list available branches; -a to include
+ remote branches
+ git branch -vv ................. list branch & annotate with head sha1 &
+ remote tracking branch
+ git branch <bname> ............. create branch with name <bname>
+ git checkout <bname> ........... switch to branch with name <bname>
+ git checkout --track <branch> .. start to locally track a remote branch
+ git push -u origin <rbname> .... push branch to origin (or other remote), and
+ setup <rbname> as tracking branch
+```
+
+## Resetting
+```markdown
+ git reset [opt] <ref|commit>
+ opt:
+ --mixed .................... resets index, but not working tree
+ --hard ..................... matches the working tree and index to that
+ of the tree being switched to any changes to
+ tracked files in the working tree since
+ <commit> are lost
+ git reset HEAD <file> .......... remove file from staging
+ git reset --soft HEAD~1 ........ delete most recent commit but keep work
+ git reset --hard HEAD~1 ........ delete most recent commit and delete work
+```
+
+## Tags
+```markdown
+ git tag -a <tname> -m "descr" ........ creates an annotated tag (full object
+ containing tagger, date, ...)
+ git tag -l ........................... list available tags
+ git checkout tag/<tname> ............. checkout specific tag
+ git checkout tag/<tname> -b <bname> .. checkout specific tag in a new branch
+```
+
+## Diff
+```markdown
+ git diff HEAD:<fname> origin/HEAD:<fname> ... diff files for different refs
+ git diff -U$(wc -l <fname>) <fname> ......... shows complete file with diffs
+ instead of usual diff snippets
+```
+
+## Log
+```markdown
+ git log --oneline .... shows log in single line per commit -> alias for
+ '--pretty=oneline --abbrev-commit'
+ git log --graph ...... text based graph of commit history
+ git log --decorate ... decorate log with REFs
+```
+
+## File history
+```markdown
+ git log -p <file> ......... show commit history + diffs for <file>
+ git log --oneline <file> .. show commit history for <file> in compact format
+```
+
+## Patching
+```markdown
+ git format-patch <opt> <since>/<revision range>
+ opt:
+ -N ................... use [PATCH] instead [PATCH n/m] in subject when
+ generating patch description (for patches spanning
+ multiple commits)
+ --start-number <n> ... start output file generation with <n> as start
+ number instead '1'
+ since spcifier:
+ -3 .................. e.g: create a patch from last three commits
+ <commit hash> ....... create patch with commits starting after <commit hash>
+
+ git am <patch> ......... apply patch and create a commit for it
+
+ git apply --stat <PATCH> ... see which files the patch would change
+ git apply --check <PATCH> .. see if the patch can be applied cleanly
+ git apply <PATCH> .......... apply the patch locally without creating a commit
+
+ # eg: generate patches for each commit from initial commit on
+ git format-patch -N $(git rev-list --max-parents=0 HEAD)
+
+ # generate single patch file from a certain commit/ref
+ git format-patch <COMMIT/REF> --stdout > my-patch.patch
+```
+
+## Submodules
+```markdown
+ git submodule add <url> [<path>] .......... add new submodule to current project
+ git clone --recursive <url> ............... clone project and recursively all
+ submodules (same as using
+ 'git submodule update --init
+ --recursive' after clone)
+ git submodule update --init --recursive ... checkout submodules recursively
+ using the commit listed in the
+ super-project (in detached HEAD)
+ git submodule update --remote <submod> .... fetch & merge remote changes for
+ <submod>, this will pull
+ origin/HEAD or a branch specified
+ for the submodule
+ git diff --submodule ...................... show commits that are part of the
+ submodule diff
+```
+
+## Inspection
+```markdown
+ git ls-tree [-r] <ref> .... show git tree for <ref>, -r to recursively ls sub-trees
+ git show <obj> ............ show <obj>
+ git cat-file -p <obj> ..... print content of <obj>
+```
+
+## Revision Specifier
+```markdown
+ HEAD ........ last commit
+ HEAD~1 ...... last commit-1
+ HEAD~N ...... last commit-N (linear backwards when in tree structure, check
+ difference between HEAD^ and HEAD~)
+ git rev-list --max-parents=0 HEAD ........... first commit
+```
diff --git a/src/tools/radare2.md b/src/tools/radare2.md
new file mode 100644
index 0000000..673c911
--- /dev/null
+++ b/src/tools/radare2.md
@@ -0,0 +1,27 @@
+# radare2(1)
+
+## print
+```markdown
+
+ pd <n> [@ <addr>] # print disassembly for <n> instructions
+ # with optional temporary seek to <addr>
+```
+
+## flags
+```markdown
+ fs # list flag-spaces
+ fs <fs> # select flag-space <fs>
+ f # print flags of selected flag-space
+```
+
+## help
+```markdown
+ ?*~<kw> # '?*' list all commands and '~' grep for <kw>
+ ?*~... # '..' less mode /'...' interactive search
+```
+
+## relocation
+```markdown
+ > r2 -B <baddr> <exe> # open <exe> mapped to addr <baddr>
+ oob <addr> # reopen current file at <baddr>
+```
diff --git a/src/tools/tmux.md b/src/tools/tmux.md
new file mode 100644
index 0000000..04b1111
--- /dev/null
+++ b/src/tools/tmux.md
@@ -0,0 +1,110 @@
+# tmux(1)
+
+Terminology:
+- `session` is a collection of pseudo terminals which can have multiple
+ `windows`
+- `window` uses the entire screen and can be split into rectangular `panes`
+- `pane` is a single pseudo terminal instance
+
+# Tmux cli
+```markdown
+# Session
+tmux creates new session
+tmux ls list running sessions
+tmux kill-session -t <s> kill running session <s>
+tmux attach -t <s> [-d] attach to session <s>, detach other clients [-d]
+tmux detach -s <s> detach all clients from session <s>
+
+# Environment
+tmux showenv -g show global tmux environment variables
+tmux setenv -g <var> <val> set variable in global tmux env
+
+# Misc
+tmux source-file <file> source config <file>
+tmux lscm list available tmux commnds
+tmux show -g show global tmux options
+tmux display <msg> display message in tmux status line
+```
+## Scripting
+```markdown
+# Session
+tmux list-sessions -F '#S' list running sessions, only IDs
+
+# Window
+tmux list-windows -F '#I' -t <s> list window IDs for session <s>
+tmux selectw -t <s>:<w> select window <w> in session <s>
+
+# Pane
+tmux list-panes -F '#P' -t <s>:<w> list pane IDs for window <w> in session <s>
+tmux selectp -t <s>:<w>.<p> select pane <p> in window <w> in session <s>
+
+# Run commands
+tmux send -t <s>:<w>.<p> "ls" C-m send cmds/keys to pane
+tmux run -t <p> <sh-cmd> run shell command <sh-cmd> in background and report output on pane -t <p>
+```
+
+For example cycle through all panes in all windows in all sessions:
+```bash
+# bash
+for s in $(tmux list-sessions -F '#S'); do
+ for w in $(tmux list-windows -F '#I' -t $s); do
+ for p in $(tmux list-panes -F '#P' -t $s:$w); do
+ echo $s:$w.$p
+ done
+ done
+done
+```
+
+# Bindings
+
+```markdown
+prefix d detach from current session
+prefix c create new window
+prefix w open window list
+prefix $ rename session
+prefix , rename window
+prefix . move current window
+```
+
+Following bindings are specific to my [`tmux.conf`](https://github.com/johannst/dotfiles/blob/master/tmux.conf):
+```markdown
+C-s prefix
+
+# Panes
+prefix s horizontal split
+prefix v vertical split
+prefix f toggle maximize/minimize current pane
+
+# Movement
+prefix Tab toggle between window
+
+prefix h move to pane left
+prefix j move to pane down
+prefix k move to pane up
+prefix l move to pane right
+
+# Resize
+prefix C-h resize pane left
+prefix C-j resize pane down
+prefix C-k resize pane up
+prefix C-l resize pane right
+
+# Copy/Paste
+prefix C-v enter copy mode
+prefix C-p paste yanked text
+prefix C-b open copy-buffer list
+
+# In Copy Mode
+v enable visual mode
+y yank selected text
+```
+
+# Command mode
+
+To enter command mode `prefix :`.
+
+Some useful commands are:
+```markdown
+setw synchronize-panes on/off enables/disables synchronized input to all panes
+list-keys -t vi-copy list keymaps for vi-copy mode
+```
diff --git a/src/tools/zsh.md b/src/tools/zsh.md
new file mode 100644
index 0000000..ae2a4bc
--- /dev/null
+++ b/src/tools/zsh.md
@@ -0,0 +1,125 @@
+# zsh(1)
+
+## Keybindings
+
+Change input mode:
+```zsh
+bindkey -v change to vi keymap
+bindkey -e change to emacs keymap
+```
+
+Define key-mappings:
+```zsh
+bindkey list mappings in current keymap
+bindkey in-str cmd create mapping for `in-str` to `cmd`
+bindkey -r in-str remove binding for `in-str`
+
+# C-v <key> dump <key> code, which can be used in `in-str`
+# zle -l list all functions for keybindings
+# man zshzle(1) STANDARD WIDGETS: get description of functions
+```
+
+## Completion
+
+### Installation
+
+Completion functions are provided via files and need to be placed in a location
+covered by `$fpath`. By convention the completion files are names as `_<CMD>`.
+
+A completion skeleton for the command `foo`, stored in `_foo`
+```zsh
+#compdef _foo foo
+
+function _foo() {
+ ...
+}
+```
+
+Alternatively one can install a completion function explicitly by calling `compdef <FUNC> <CMD>`.
+
+### Completion Variables
+
+Following variables are available in Completion functions:
+```zsh
+$words # array with command line in words
+$#words # number words
+$CURRENT # index into $words for cursor position
+$words[CURRENT-1] # previous word (relative to cursor position)
+```
+
+### Completion Functions
+- `_describe` simple completion, just words + description
+- `_arguments` sophisticated completion, allow to specify actions
+
+#### Completion with [`_describe`][zsh-comp-utils]
+```zsh
+_describe MSG COMP
+```
+- `MSG` simple string with header message
+- `COMP` array of completions where each entry is `"opt:description"`
+
+```zsh
+function _foo() {
+ local -a opts
+ opts=('bla:desc for bla' 'blu:desc for blu')
+ _describe 'foo-msg' opts
+}
+compdef _foo foo
+
+foo <TAB><TAB>
+ -- foo-msg --
+bla -- desc for bla
+blu -- desc for blu
+```
+
+#### Completion with [`_arguments`][zsh-comp-utils]
+```zsh
+_arguments SPEC [SPEC...]
+```
+where `SPEC` can have one of the following forms:
+- `OPT[DESC]:MSG:ACTION`
+- `N:MSG:ACTION`
+
+Available actions
+```zsh
+(op1 op2) list possible matches
+->VAL set $state=VAL and continue, `$state` can be checked later in switch case
+FUNC call func to generate matches
+{STR} evaluate `STR` to generate matches
+```
+
+### Example
+Skeleton to copy/paste for writing simple completions.
+
+Assume a program `foo` with the following interface:
+```zsh
+foo -c green|red|blue -s low|high -f <file> -d <dir> -h
+```
+
+The completion handler could be implemented as follows in a file called `_foo`:
+```zsh
+#compdef _foo foo
+
+function _foo_color() {
+ local colors=()
+ colors+=('green:green color')
+ colors+=('red:red color')
+ colors+=('blue:blue color')
+ _describe "color" colors
+}
+
+function _foo() {
+ _arguments \
+ "-c[define color]:color:->s_color" \
+ "-s[select sound]:color:(low high)" \
+ "-f[select file]:file:_files" \
+ "-d[select dir]:fir:_files -/" \
+ "-h[help]"
+
+ case $state in
+ s_color) _foo_color;;
+ esac
+}
+```
+
+[zsh-comp-utils]: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions