diff options
author | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-05-01 14:47:26 +0200 |
---|---|---|
committer | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-05-01 14:49:10 +0200 |
commit | 50e07a8bca68d2f568df44166fa94383141c2696 (patch) | |
tree | 087c1a6dfce9745782cc62c021f2c0833077569b /src/tools | |
parent | 1c20849c87f2d936ec599b56f965507dee97ade6 (diff) | |
download | notes-50e07a8bca68d2f568df44166fa94383141c2696.tar.gz notes-50e07a8bca68d2f568df44166fa94383141c2696.zip |
shells: move shells into own group
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/README.md | 3 | ||||
-rw-r--r-- | src/tools/bash.md | 259 | ||||
-rw-r--r-- | src/tools/fish.md | 280 | ||||
-rw-r--r-- | src/tools/zsh.md | 371 |
4 files changed, 0 insertions, 913 deletions
diff --git a/src/tools/README.md b/src/tools/README.md index 89b6c39..41584d0 100644 --- a/src/tools/README.md +++ b/src/tools/README.md @@ -1,8 +1,5 @@ # Tools -- [zsh](./zsh.md) -- [bash](./bash.md) -- [fish](./fish.md) - [tmux](./tmux.md) - [git](./git.md) - [awk](./awk.md) diff --git a/src/tools/bash.md b/src/tools/bash.md deleted file mode 100644 index f27b3a2..0000000 --- a/src/tools/bash.md +++ /dev/null @@ -1,259 +0,0 @@ -# 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 value -bar=${foo:-some_val} # if $foo set, then bar=$foo else bar=some_val - -# alternate value -bar=${foo:+bla $foo} # if $foo set, then bar="bla $foo" else bar="" - -# 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 - -# set programmatically with priintf builtin -printf -v "VAR1" "abc" -NAME=VAR2 -printf -v "$NAME" "%s" "def" -``` - -> 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 -``` - -With `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 -``` -> The article [Bash One-Liners Explained, Part III: All about -> redirections](https://catonmat.net/bash-one-liners-explained-part-three) -> contains some nice visualization to explain bash redirections. - -### 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` - -## Process substitution ([ref][psub]) - -Process substitution allows to redirect the stdout of multiple processes at -once. -```bash -vim -d <(grep foo bar) <(grep foo moose) -``` - -## Command grouping - -Execute commands in a group with or without subshell. Can be used to easily -redirect stdout/stderr of all commands in the group into one file. -```bash -# Group commands without subshell. -v=abc ; { v=foo; echo $v; } ; echo $v -# foo -# foo - -# Group commands with subshell. -v=abc ; ( v=foo; echo $v; ) ; echo $v -# foo -# abc -``` - -## Argument parsing with `getopts` - -The `getopts` builtin uses following global variables: -- `OPTARG`, value of last option argument -- `OPTIND`, index of the next argument to process (user must reset) -- `OPTERR`, display errors if set to `1` - -```bash -getopts <optstring> <param> [<args>] -``` -- `<optstring>` specifies the names of supported options, eg `f:c` - - `f:` means `-f` option with an argument - - `c` means `-c` option without an argument -- `<param>` specifies a variable name which `getopts` fills with the last parsed option argument -- `<args>` optionally specify argument string to parse, by default `getopts` parses `$@` - -### Example -```bash -#!/bin/bash -function parse_args() { - while getopts "f:c" PARAM; do - case $PARAM in - f) echo "GOT -f $OPTARG";; - c) echo "GOT -c";; - *) echo "ERR: print usage"; exit 1;; - esac - done - # users responsibility to reset OPTIND - OPTIND=1 -} - -parse_args -f xxx -c -parse_args -f yyy -``` - -## Regular Expressions - -Bash supports regular expression matching with the binary operator `=~`. -The match results can be accessed via the `$BASH_REMATCH` variable: -- `${BASH_REMATCH[0]}` contains the full match -- `${BASH_REMATCH[1]}` contains match of the first capture group - -```bash -INPUT='title foo : 1234' -REGEX='^title (.+) : ([0-9]+)$' -if [[ $INPUT =~ $REGEX ]]; then - echo "${BASH_REMATCH[0]}" # title foo : 1234 - echo "${BASH_REMATCH[1]}" # foo - echo "${BASH_REMATCH[2]}" # 1234 -fi -``` -> **Caution**: When specifying a `regex` in the `[[ ]]` block directly, quotes will be treated as part of the pattern. -> `[[ $INPUT =~ "foo" ]]` will match against `"foo"` not `foo`! - -## 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 -[psub]: https://tldp.org/LDP/abs/html/process-sub.html diff --git a/src/tools/fish.md b/src/tools/fish.md deleted file mode 100644 index a499e10..0000000 --- a/src/tools/fish.md +++ /dev/null @@ -1,280 +0,0 @@ -# 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 -``` - -### Special Variables [ref](https://fishshell.com/docs/current/language.html#special-variables) -```sh -$status # exit code of last command -$pipestatus # list of exit codes of pipe chain - -$fish_pid # pid of parent fish shell ($$ in bash) -$last_pid # pid of last started process ($! in bash) - -$CMD_DURATION # runtime of last command in ms -``` - -### Lists -In `fish` all variables are lists (start with index `1`, but lists can't -contain lists. -```sh -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. -```sh -set foo a; set a 1337 -echo $$foo # outputs 1337 -``` - -Cartesian product. -```sh -echo file.{h,cc} -# file.h file.cc - -echo {a,b}{1,2} -# a1 b1 a2 b2 -``` - -#### `*PATH` [ref](https://fishshell.com/docs/current/language.html#path-variables) -Lists ending with `PATH` are automatically split at `:` when used and joined -with `:` when quoted or exported to the environment. -```sh -set -x BLA_PATH a:b:c:d -echo $BLA_PATH # a b c d -echo "$BLA_PATH" # a:b:c:d (quoted) -env | grep BLA_PATH # BLA_PATH=a:b:c:d (env) - -set FOO_PATH x y z -echo $FOO_PATH # x y z -echo "$FOO_PATH" # x:y:z -``` - -## Command Handling -```sh -# sub-commands are not run in quotes -echo "ls output: "(ls) -``` - -### I/O redirection -```sh -# 'noclobber', fail if 'log' already exists -echo foo >? log -``` - -### Process substitution -Redirect output of multiple processes. Same as `<(..)` in bash. -```sh -diff (sort a | psub) (sort b | psub) -``` - -## Control Flow -### `if` / `else` -```sh -if grep foo bar - # do sth -else if grep foobar bar - # do sth else -else - # do sth else -end -``` - -### `switch` -```sh -switch (echo foo) -case 'foo*' - # do start with foo -case bar dudel - # do bar and dudel -case '*' - # do else -end -``` - -### `while` Loop -```sh -while true - echo foo -end -``` - -### `for` Loop -```sh -for f in (ls) - echo $f -end -``` - -## Functions -Function arguments are passed via `$argv` list. -```sh -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 -```sh -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 -``` - -### Argument parsing and completion -`argparse` puts options into variables of name `_flag_NAME`. - -References: -- [Argument Handling](https://fishshell.com/docs/current/language.html#argument-handling) -- [`argparse`](https://fishshell.com/docs/current/cmds/argparse.html) -- [Writing your own completions](https://fishshell.com/docs/current/completions.html) -- [`complete`](https://fishshell.com/docs/current/cmds/complete.html) - -```sh -function moose --d "my moose fn" - # h/help : short / long option (boolean) - # color : only long option (boolean) - # u/user= : option with required argument, only last specified is taken - # f/file+= : option with required argument, can be specified multiple times - # - argparse h/help color= u/user= f/file=+ -- $argv - or return - - if set -ql _flag_help - echo "usage ..." - return 0 - end - - set -ql _flag_file - and echo "file=$_flag_file | cnt:" (count $_flag_file) - - set -ql _flag_color - and echo "color=$_flag_color" - - set -ql _flag_user - and echo "user=$_flag_user" -end - -# Delete all previous defined completions for 'moose'. -complete -c moose -e - -# Don't complete files for command. -complete -c moose --no-files - -# Help completion. -# -n specifies a conditions. The completion is only active if the command -# returns 0. -complete -c moose -s h -l help -n "not __fish_contains_opt -s h help" \ - --description "Print usage help and exit" - -# File completion. -# -F force complete files (overwrite --no-files). -# -r requires argument. -complete -c moose -s f -l file -F -r \ - --description "Specify file (can be passed multiple times)" - -# Color completion. -# -a options for completion. -# -x short for -r and --no-files (-f) -complete -c moose -x -l color -a "red blue" \ - --description "Specify a color." - -# User completion. -# -a options for completion. Call a function to generate arguments. -complete -c moose -x -s u -l user -a "(__fish_complete_users)" \ - --description "Specify a user" -``` - -## Prompt -The prompt is defined by the output of the `fish_prompt` function. -```sh -function fish_prompt - set -l cmd_ret - echo "> "(pwd) $cmd_ret" " -end -``` -> Use `set_color` to manipulate terminal colors and `set_color -c` to print the -> current colors. - - -## Useful Builtins -List all builtins with `builtins -n`. - -```sh -# history -history search <str> # search history for <str> -history merge # merge histories from fish sessions - -# list -count $var # count elements in list - -contains /bin $PATH # return 0 (true) 1 (false) -contains -i /bin $PATH # additionally print index on stdout - -# string -string split SEP STRING - -# math -math -b hex 4096 # output dec as hex -math 0x1000 # output hex as dec -math "log2(1024)" # call functions -math -s0 7/3 # integer division (by default float) - -# status -status -f # abs path of current file -``` - -## 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 - Alt-Left / Alt - Right . prevd / nextd, walk dir history -``` - -## 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/zsh.md b/src/tools/zsh.md deleted file mode 100644 index f702655..0000000 --- a/src/tools/zsh.md +++ /dev/null @@ -1,371 +0,0 @@ -# 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 -``` - -Access edit buffer in zle widget: -```zsh -$BUFFER # Entire edit buffer content -$LBUFFER # Edit buffer content left to cursor -$RBUFFER # Edit buffer content right to cursor - -# create zle widget which adds text right of the cursor -function add-text() { - RBUFFER="some text $RBUFFER" -} -zle -N add-text - -bindkey "^p" add-text -``` - -## Parameter - -Default value: -```zsh -# default value -echo ${foo:-defval} # defval -foo=bar -echo ${foo:-defval} # bar -``` - -Alternative value: -```zsh -echo ${foo:+altval} # '' -foo=bar -echo ${foo:+altval} # altval -``` - -Check variable set, error if not set: -```zsh -echo ${foo:?msg} # print `msg` and return errno `1` -foo=bar -echo ${foo:?msg} # bar -``` - -Sub-string `${var:offset:length}`: -```zsh -foo=abcdef -echo ${foo:1:3} # bcd -``` - -Trim prefix `${var#prefix}`: -```zsh -foo=bar.baz -echo ${foo#bar} # .baz -``` - -Trim suffix `${var%suffix}`: -```zsh -foo=bar.baz -echo ${foo%.baz} # bar -``` - -Substitute pattern `${var/pattern/replace}`: -```zsh -foo=aabbccbbdd -echo ${foo/bb/XX} # aaXXccbbdd -echo ${foo//bb/XX} # aaXXccXXdd -# replace prefix -echo ${foo/#bb/XX} # aabbccbbdd -echo ${foo/#aa/XX} # XXbbccbbdd -# replace suffix -echo ${foo/%bb/XX} # aabbccbbdd -echo ${foo/%dd/XX} # aabbccbbXX -``` - -> Note: `prefix`/`suffix`/`pattern` are expanded as pathnames. - -## Variables - -```zsh -# Variable with local scope -local var=val - -# Read-only variable -readonly var=bal -``` - -Indexed arrays: -```zsh -arr=(aa bb cc dd) -echo $arr[1] # aa -echo $arr[-1] # dd - -arr+=(ee) -echo $arr[-1] # ee - -echo $arr[1,3] # aa bb cc -``` - -Associative arrays: -```zsh -typeset -A arr -arr[x]='aa' -arr[y]='bb' -echo $arr[x] # aa -``` - -Tied arrays: -```zsh -typeset -T VEC vec=(1 2 3) '|' - -echo $vec # 1 2 3 -echo $VEC # 1|2|3 -``` - -Unique arrays (set): -``` -typeset -U vec=(1 2 3) - -echo $vec # 1 2 3 -vec+=(1 2 4) -echo $vec # 1 2 3 4 -``` - -### Expansion Flags - -Join array to string `j:sep:`: -```zsh -foo=(1 2 3 4) -echo ${(j:-:)foo} # 1-2-3-4 -echo ${(j:\n:)foo} # join with new lines -``` - -Split string to array `s:sep`: -```zsh -foo='1-2-3-4' -bar=(${(s:-:)foo}) # capture as array -echo $bar # 1 2 3 4 -echo $bar[2] # 2 -``` - -Upper/Lower case string: -```zsh -foo=aaBB -echo ${(L)foo} # aabb -echo ${(U)foo} # AABB -``` - -Key/values in associative arrays: -```zsh -typeset -A vec; vec[a]='aa'; vec[b]='bb' - -echo ${(k)vec} # a b -echo ${(v)vec} # aa bb -echo ${(kv)vec} # a aa b bb - -# Iterate over key value pairs. -for k v in ${(kv)vec)}; do ...; done -``` - -## I/O redirections - -See [bash - I/O redirection](bash.md#io-redirection) - -## Process substitution - -Process substitution allows to redirect the stdout of multiple processes at -once. -```bash -vim -d <(grep foo bar) <(grep foo moose) -``` - -## Argument parsing with `zparseopts` - -```zsh -zparseopts [-D] [-E] [-A assoc] specs -``` -Arguments are copied into the associative array `assoc` according to `specs`. -Each spec is described by an entry as `opt[:][=array]`. -- `opt` is the option without the `-` char. Passing `-f` is matched against `f` - opt, `--long` is matched against `-long`. -- Using `:` means the option will take an argument. -- The optional `=array` specifies an alternate storage container where this - option should be stored. -> Documentation can be found in `man zshmodules`. - -### Example -```zsh -#!/bin/zsh -function test() { - zparseopts -D -E -A opts f=flag o: -long: - echo "flag $flag" - echo "o $opts[-o]" - echo "long $opts[--long]" - echo "pos $1" -} - -test -f -o OPTION --long LONG_OPT POSITIONAL - -# Outputs: -# flag -f -# o OPTION -# long LONG_OPT -# pos POSITIONAL -``` - -## Regular Expressions - -Zsh supports regular expression matching with the binary operator `=~`. -The match results can be accessed via the `$MATCH` variable and -`$match` indexed array: -- `$MATCH` contains the full match -- `$match[1]` contains match of the first capture group - -```zsh -INPUT='title foo : 1234' -REGEX='^title (.+) : ([0-9]+)$' -if [[ $INPUT =~ $REGEX ]]; then - echo "$MATCH" # title foo : 1234 - echo "$match[1]" # foo - echo "$match[2]" # 1234 -fi -``` - -## 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-fn] -```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-fn] -```zsh -_arguments SPEC [SPEC...] -``` -where `SPEC` can have one of the following forms: -- `OPT[DESC]:MSG:ACTION` for option flags -- `N:MSG:ACTION` for positional arguments - -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]:sound:(low high)" \ - "-f[select file]:file:_files" \ - "-d[select dir]:dir:_files -/" \ - "-h[help]" - - case $state in - s_color) _foo_color;; - esac -} -``` - -### Example with optional arguments -For this example we assume that the command `foo` takes at least three optional -arguments such as -```zsh -foo arg1 arg2 arg3 [argN..] -``` - -```zsh -function _foo() { - _arguments \ - "1:opt 1:(a b c)" \ - ":opt next:(d e f)" \ - "*:opt all:(u v w)" -} -``` -Explanation: -- `1:MSG:ACTION` sets completion for the **first** optional argument -- `:MSG:ACTION` sets completion for the **next** optional argument -- `*:MSG:ACTION` sets completion for the optional argument where none of the - previous rules apply, so in our example for `arg3, argN..`. - -> `_files` is a zsh builtin utility function to complete files/dirs see -> - [zsh completion functions][zsh-comp-fn] -> - [zsh completion utility functions][zsh-comp-utility-fn] - - -[zsh-comp-fn]: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions -[zsh-comp-utility-fn]: https://github.com/zsh-users/zsh-completions/blob/master/zsh-completions-howto.org#utility-functions |