From 3fd0e3f5cbddbd366c84ea3563f18de314e45fd7 Mon Sep 17 00:00:00 2001 From: Denis Isidoro Date: Fri, 20 Sep 2019 10:38:58 -0300 Subject: [PATCH] First commit --- sheets/awk.cheat | 4 +++ sheets/crontab.cheat | 7 +++++ sheets/docker.cheat | 40 +++++++++++++++++++++++++++ sheets/git.cheat | 13 +++++++++ sheets/kubernetes.cheat | 7 +++++ sheets/mysql.cheat | 10 +++++++ sheets/network.cheat | 13 +++++++++ sheets/tar.cheat | 24 ++++++++++++++++ src/arg.sh | 54 ++++++++++++++++++++++++++++++++++++ src/cheat.sh | 33 ++++++++++++++++++++++ src/cheats | 61 +++++++++++++++++++++++++++++++++++++++++ src/docs.sh | 8 ++++++ src/misc.sh | 6 ++++ src/selection.sh | 27 ++++++++++++++++++ src/str.sh | 27 ++++++++++++++++++ src/ui.sh | 17 ++++++++++++ 16 files changed, 351 insertions(+) create mode 100644 sheets/awk.cheat create mode 100644 sheets/crontab.cheat create mode 100644 sheets/docker.cheat create mode 100644 sheets/git.cheat create mode 100644 sheets/kubernetes.cheat create mode 100644 sheets/mysql.cheat create mode 100644 sheets/network.cheat create mode 100644 sheets/tar.cheat create mode 100644 src/arg.sh create mode 100644 src/cheat.sh create mode 100755 src/cheats create mode 100644 src/docs.sh create mode 100644 src/misc.sh create mode 100644 src/selection.sh create mode 100644 src/str.sh create mode 100644 src/ui.sh diff --git a/sheets/awk.cheat b/sheets/awk.cheat new file mode 100644 index 0000000..984e8c7 --- /dev/null +++ b/sheets/awk.cheat @@ -0,0 +1,4 @@ +% awk, text processing, string + +# Print nth column +awk '{print $} \ No newline at end of file diff --git a/sheets/crontab.cheat b/sheets/crontab.cheat new file mode 100644 index 0000000..4598420 --- /dev/null +++ b/sheets/crontab.cheat @@ -0,0 +1,7 @@ +% crontab, scheduling + +# List cron jobs +crontab -l + +# Edit cron job +crontab -e \ No newline at end of file diff --git a/sheets/docker.cheat b/sheets/docker.cheat new file mode 100644 index 0000000..098b3a5 --- /dev/null +++ b/sheets/docker.cheat @@ -0,0 +1,40 @@ +% docker, container + +# Remove an image +docker image rm + +# Delete an image from the local image store +docker rmi + +# List all images that are locally stored with the Docker engine +docker images + +# Build an image from the Dockerfile in the current directory and tag the image +docker build -t : . + +# Pull an image from a registry +docker pull : + +# Stop a running container through SIGTERM +docker stop + +# Stop a running container through SIGKILL +docker kill + +# List the networks +docker network ls + +# List the running containers +docker ps + +# Delete all running and stopped containers +docker rm -f $(docker ps -aq) + +# Create a new bash process inside the container and connect it to the terminal +docker exec -it bash + +# Print the last lines of a container’s logs +docker logs --tail 100 | less + +$ image_id: docker images --- --headers 1 --column 3 +$ container_id: docker ps --- --headers 1 --column 1 \ No newline at end of file diff --git a/sheets/git.cheat b/sheets/git.cheat new file mode 100644 index 0000000..45226dd --- /dev/null +++ b/sheets/git.cheat @@ -0,0 +1,13 @@ +% git + +# Clear everything +git clean -dxf + +# Sign all commits in a branch based on master +git rebase master -S -f + +# Checkout to branch +# Change branch +git checkout + +$ branch: git branch --format='%(refname:short)' diff --git a/sheets/kubernetes.cheat b/sheets/kubernetes.cheat new file mode 100644 index 0000000..f4dfba3 --- /dev/null +++ b/sheets/kubernetes.cheat @@ -0,0 +1,7 @@ +% kubernetes, k8s + +# Edit deployment +kubectl edit deployment + +# Get pods +kubectl get pods diff --git a/sheets/mysql.cheat b/sheets/mysql.cheat new file mode 100644 index 0000000..accff79 --- /dev/null +++ b/sheets/mysql.cheat @@ -0,0 +1,10 @@ +% mysql, database, db + +# Create database +mysql -u -p -e "create database $database character set UTF8mb4 collate utf8mb4_bin" + +# Export databse +mysqldump -u -p > + +# Import database +mysql -u -p diff --git a/sheets/network.cheat b/sheets/network.cheat new file mode 100644 index 0000000..1ea7fef --- /dev/null +++ b/sheets/network.cheat @@ -0,0 +1,13 @@ +% network + +# Kill a process running on a given port +lsof -i : | awk '{l=$2} END {print l}' | xargs kill + +# List IP addresses connected on a given port +netstat -tn 2>/dev/null | grep : | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head + +# Find external, public IP address +dig +short myip.opendns.com @resolver1.opendns.com + +# Find primary, local IP address +ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' \ No newline at end of file diff --git a/sheets/tar.cheat b/sheets/tar.cheat new file mode 100644 index 0000000..d5b9c6e --- /dev/null +++ b/sheets/tar.cheat @@ -0,0 +1,24 @@ +% tar, zip, gzip, compression + +# Create a tar containing files +tar cf .tar + +# Extract the files from a tar +tar xf + +# Create a tar with Gzip compression +tar czf .tar.gz + +# Extract a tar using Gzip +tar xzf + +# Compress file and appends .gz to its name +gzip + +# Decompress compressed file +gzip -d + +$ path: ls +$ tar_file: ls *.tar +$ targz_file: ls *.tar.gz +$ gz_file: ls *.gz \ No newline at end of file diff --git a/src/arg.sh b/src/arg.sh new file mode 100644 index 0000000..418919c --- /dev/null +++ b/src/arg.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +arg::fn() { + awk -F'---' '{print $1}' +} + +arg::opts() { + awk -F'---' '{print $2}' +} + +arg::interpolate() { + local readonly arg="$1" + local readonly value="$2" + + sed "s|<${arg}>|\"${value}\"|g" +} + +arg::next() { + grep -Eo '<[0-9a-zA-Z\-_]+>' \ + | head -n1 \ + | tr -d '<' \ + | tr -d '>' +} + +arg::pick() { + local readonly arg="$1" + local readonly cheat="$2" + + local readonly prefix="$ ${arg}:" + local readonly length="$(echo "$prefix" | str::length)" + local readonly arg_description="$(grep "$prefix" "$cheat" | str::sub $((length + 1)))" + + local readonly fn="$(echo "$arg_description" | arg::fn)" + local readonly args_str="$(echo "$arg_description" | arg::opts | tr ' ' '\n' || echo "")" + local arg_name="" + + for arg_str in $args_str; do + if [ -z $arg_name ]; then + arg_name="$(echo "$arg_str" | str::sub 2)" + else + eval "local $arg_name"='$arg_str' + arg_name="" + fi + done + + if [ -n "$fn" ]; then + eval "$fn" | ui::pick --prompt "$arg: " --header-lines "${headers:-0}" | str::column "${column:-}" + else + printf "\033[0;36m${arg}:\033[0;0m " > /dev/tty + read value + ui::clear_previous_line > /dev/tty + printf "$value" + fi +} diff --git a/src/cheat.sh b/src/cheat.sh new file mode 100644 index 0000000..2683cc2 --- /dev/null +++ b/src/cheat.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +cheat::find() { + find "${cheat_folder:-"${DIR}/../sheets"}" -iname '*.cheat' +} + +cheat::read_many() { + for cheat in $(cat); do + awk ' + function color(c,s) { + printf("\033[%dm%s\033[0m",30+c,s) + } + + /^%/ { tags=substr($0, 3); next } + /^#/ { print color(3, tags"^") color(4, $0); next } + /^\$/ { next } + NF { print color(3, tags"^") color(7, $0); next }' "$cheat" + done +} + +cheat::from_selection() { + local readonly cheats="$1" + local readonly selection="$2" + + local readonly tags="$(echo "$selection" | selection::tags)" + + for cheat in $cheats; do + if grep -q "% $tags" "$cheat"; then + echo "$cheat" + break + fi + done +} diff --git a/src/cheats b/src/cheats new file mode 100755 index 0000000..8b47b5a --- /dev/null +++ b/src/cheats @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -euo pipefail + +export DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" + +source "${DIR}/arg.sh" +source "${DIR}/cheat.sh" +source "${DIR}/docs.sh" +source "${DIR}/misc.sh" +source "${DIR}/selection.sh" +source "${DIR}/str.sh" +source "${DIR}/ui.sh" + +##? Command cheatsheet tool +##? +##? Usage: +##? cheats [options] +##? +##? Options: +##? --print Prevent script execution [default: false] +##? --no-interpolation Prevent argument interpolation [default: false] +##? -c --cheat-folder Folder with cheatsheets + +docs::eval "$@" + +main() { + local readonly cheats="$(cheat::find)" + local readonly selection="$(ui::select "$cheats")" + local readonly cheat="$(cheat::from_selection "$cheats" "$selection")" + local cmd="$(selection::command "$selection" "$cheat")" + local arg value + + if $no_interpolation; then + echo "$cmd" + exit 0 + fi + + while true; do + arg="$(echo "$cmd" | arg::next || echo "")" + if [ -z "$arg" ]; then + break + fi + + value="$(arg::pick "$arg" "$cheat" || echo "")" + if [ -z "$value" ]; then + echo "$cmd" + exit 0 + fi + + eval "local $arg"='$value' + cmd="$(echo "$cmd" | arg::interpolate "$arg" "$value")" + done + + if $print; then + echo "$cmd" + else + eval "$cmd" + fi +} + +main "$@" \ No newline at end of file diff --git a/src/docs.sh b/src/docs.sh new file mode 100644 index 0000000..73b8fe4 --- /dev/null +++ b/src/docs.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +docs::eval() { + print=false + no_interpolation=false + cheat_folder="" +} diff --git a/src/misc.sh b/src/misc.sh new file mode 100644 index 0000000..3efd1bd --- /dev/null +++ b/src/misc.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +# no-op hack to set dependency order resolution +dep() { + : +} diff --git a/src/selection.sh b/src/selection.sh new file mode 100644 index 0000000..baab514 --- /dev/null +++ b/src/selection.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +selection::core() { + cut -d'^' -f2 +} + +selection::tags() { + cut -d'^' -f1 +} + +selection::core_is_comment() { + grep -qE '^#' +} + +selection::command() { + local readonly selection="$1" + local readonly cheat="$2" + + local readonly core="$(echo $selection | selection::core)" + + if echo "$core" | selection::core_is_comment; then + grep "$core" "$cheat" -A999 \ + | str::last_paragraph_line + else + echo "$core" + fi +} diff --git a/src/str.sh b/src/str.sh new file mode 100644 index 0000000..b2a66b8 --- /dev/null +++ b/src/str.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +str::length() { + awk '{print length}' +} + +str::sub() { + local readonly start="${1:-0}" + local readonly finish="${2:-99999}" + + cut -c "$((start + 1))-$((finish - 1))" +} + +str::column() { + local readonly n="${1:-}" + + if [ -n "$n" ]; then + awk "{print \$$n}" + else + cat + fi +} + +str::last_paragraph_line() { + awk '(!NF) { exit } { print $0 }' \ + | tail -n1 +} diff --git a/src/ui.sh b/src/ui.sh new file mode 100644 index 0000000..608a16e --- /dev/null +++ b/src/ui.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +ui::pick() { + fzf --inline-info "$@" +} + +ui::select() { + local readonly cheats="$1" + + echo "$cheats" \ + | cheat::read_many \ + | ui::pick -i --ansi --delimiter '\^' --with-nth 2 +} + +ui::clear_previous_line() { + tput cuu1 && tput el || true +}