# Common RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' NC='\033[0m' # Install latest version and remove previous one # asdflatestreplace function asdflatestreplace() { asdf install $1 latest asdf global $1 latest local_version=`asdf list $1 | tail -1 | xargs` asdf uninstall $1 $local_version } # Base64 encode a string function b64() { echo -n "$*" | base64 } function b64decode() { echo -n "$*" | base64 --decode } # Usage: cht language/something function cht() { curl cht.sh/`echo $* | tr ' ' +` } # Recursively delete `.DS_Store` files # Recursively clear application cache and logss function cleanup() { find . -type f -name '*.DS_Store' -ls -delete fd -t d '(cache|log)' ~/dev ~ | grep -E '(app|var)/(cache|log)' | xargs rm -rf } # Preview CSVs function csvpreview() { sed 's/,,/, ,/g;s/,,/, ,/g' "$@" | column -s, -t | less -#2 -N -S } # Recursively check if a file contains a word at least twice # Usage: findduplicateword function findduplicateword() { grep -ro -c "$1" * | awk -F: '{ if ($2 > 1) { print $1 } }' } # Keep header line while doing a grep # Usage: ps aux | hgrep ssh function hgrep() { echo -n "\033[32m"; head -1; echo -n "\033[39m"; grep $* } # Keep header line while doing a grep (when having 2 header lines) # Usage: ps aux | hhgrep ssh function hhgrep() { echo -n "\033[32m"; head -2; echo -n "\033[39m"; grep $* } # Usage: encrypt # Then, a password is prompted function encrypt() { input=$* if [ -z "$input" ]; then input=`cat $filename echo -e "------------\n${YELLOW}Encrypted output has been stored into following file:${NC}" echo -e "$filename" echo -e "------------" echo -e "${YELLOW}To decrypt the value, use:" echo -e "${GREEN}\$${NC} cat \"$filename\" | openssl base64 -d | openssl enc -d -aes-256-cbc" else echo -e "------------\n${YELLOW}Encrypted output:${NC}" echo -e "$result" echo -e "------------" echo -e "${YELLOW}To decrypt the value, use:" echo -e "${GREEN}\$${NC} echo \"$result\" | openssl base64 -d | openssl enc -d -aes-256-cbc" fi } # Usage: decrypt # Then, a password is prompted function decrypt() { echo "$*" | openssl base64 -d | openssl enc -d -aes-256-cbc } # Usage: encryptfile (default: file.gpg) function encryptfile() { output="$1.gpg" if [ -n "$2" ]; then output="$2" fi gpg2 --encrypt --recipient vincent --output $output $1 } # Run 'diskutil list' and choose disk to erase # Usage: erasedisk function erasedisk() { diskutil eraseDisk jhfs+ EDD gpt $1 ; diskutil list } # Usage: decryptfile function decryptfile() { command="gpg2 --decrypt $1" if [ -n "$2" ]; then command="$command > $2" fi eval $command } # Clones if a Git repository is given, elsewhere just cd function cdc() { name=`sed -e 's/.*\///g' <<< $1` if [[ ! -d "$1" && $1 =~ ^(github|bitbucket|gitlab)\.[a-z]{2,}/.*$ ]]; then ssh=`sed -e 's/^/git@/' -e 's/$/.git/' -e 's/\//:/' <<< $1` git clone $ssh; fi cd $name; } # Usage: git-delete-branches # Pickup branches you want to delete with and then press function git-delete-branches() { git branch | grep --invert-match '\*' | cut -c 3- | fzf --multi --preview="git log {} --" | xargs git branch --delete --force } # Usage: git-pr-checkout # Select the pull-request you want to checkout locally function git-pr-checkout() { local jq_template pr_number jq_template='"'\ '#\(.number) - \(.title)'\ '\t'\ 'Author: \(.user.login)\n'\ 'Created: \(.created_at)\n'\ 'Updated: \(.updated_at)\n\n'\ '\(.body)'\ '"' pr_number=$( gh api 'repos/:owner/:repo/pulls' | jq ".[] | $jq_template" | sed -e 's/"\(.*\)"/\1/' -e 's/\\t/\t/' | fzf \ --with-nth=1 \ --delimiter='\t' \ --preview='echo -e {2}' \ --preview-window=top:wrap | sed 's/^#\([0-9]*\).*/\1/' ) if [ -n "$pr_number" ]; then gh pr checkout "$pr_number" fi } # Determines size of a file or total size of a directory function fs() { if du -b /dev/null > /dev/null 2>&1; then local arg=-sbh; else local arg=-sh; fi if [[ -n "$@" ]]; then du $arg -- "$@"; else du $arg .[^.]* ./*; fi; } # Creates a data URL from a file function dataurl() { local mimeType=$(file -b --mime-type "$1"); if [[ $mimeType == text/* ]]; then mimeType="${mimeType};charset=utf-8"; fi echo "data:${mimeType};base64,$(openssl base64 -in "$1" | tr -d '\n')"; } # Returns useful information using dig tool function diga() { dig +nocmd "$1" any +multiline +noall +answer; } # Returns information about usual subdomains function dig_in_parallel() { dig=$(dig +noall +answer $1); if [ -n "$dig" ]; then echo "✔ $dig"; fi } # Fetches top 100000 subdomains list and test it against given domain # Usage: digscan function digscan() { set +m; echo "Fetching subdomain list...\n"; curl -s -o /tmp/subdomains https://raw.githubusercontent.com/internetwache/CT_subdomains/master/top-100000.txt echo "Checking...\n"; while IFS=, read -r count subdomain do dig_in_parallel "$subdomain.$1" & sleep 0.05 done < /tmp/subdomains wait set -m; } # This function is used by other functions to print and then run the specified command # Usage: echo_and_run your command and arguments function echo_and_run() { command=$@ echo "$ $command" bash -c "$command" } # This function allows to rename multiple directories in a specified root directory # Usage: dirrename old new function dirrename() { for file in $(find . -type d -name "$1*"); do mv $file $(echo "$file" | sed "s/$1/$2/"); done } # This function allows to rename multiple files in a directory # Usage: filerename old new function filerename() { for file in $(find . -type f -name "$1*"); do mv $file $(echo "$file" | sed "s/$1/$2/"); done } # Transforms a video file to a gif # Usage: gify [ ] function gify { ratio=${5:-480:270} fpm=${6:-60} ffmpeg -i $1 -vf scale=$ratio -r $fpm -ss $3 -t $4 $2 } # Usage: jwt function jwt { jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $(echo $1) } # Usage: lighthouse function lighthouse { result=`curl -s https://builder-dot-lighthouse-ci.appspot.com/stream\?url=$1\&format=$2 | grep done | cut -d' ' -f3` if [[ $2 == "json" ]]; then curl -s $result else echo "Report available: $result" fi } # Asks the user to select a network interface and returns the result function selectnetworkinterface() { echo "Select the network interface:\n1) Belkin USB-C LAN\n2) Wi-Fi" read n case $n in 1) selected="Belkin USB-C LAN";; 2) selected="Wi-Fi";; *) echo "Invalid option"; return;; esac } # Sets Cloudflare DNS servers on a network interface function opendns() { selectnetworkinterface echo "\n-> Setting open DNS servers on network interface '$selected'" networksetup -setdnsservers "$selected" 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001 } # Sets an HTTP proxy on a network interface # Usage: httpproxy 127.0.0.1 9050 function httpproxy() { selectnetworkinterface # prepare proxy configuration networksetup -setwebproxy "$selected" $* networksetup -setwebproxystate "$selected" on echo "-> Running proxy on $*" trap 'echo caught signal: SIGINT' SIGINT sleep 86400 # when tor is stopped, remove proxy networksetup -setwebproxystate "$selected" off trap - SIGINT echo "-> Done: proxy is stopped, config reset" } # Sets an HTTPS proxy on a network interface # Usage: httpsproxy 127.0.0.1 9050 function httpsproxy() { selectnetworkinterface # prepare proxy configuration networksetup -setsecurewebproxy "$selected" $* networksetup -setsecurewebproxystate "$selected" on echo "-> Running proxy on $*" trap 'echo caught signal: SIGINT' SIGINT sleep 86400 # when tor is stopped, remove proxy networksetup -setsecurewebproxystate "$selected" off trap - SIGINT echo "-> Done: proxy is stopped, config reset" } # Sets SSH proxy on a network interface # Usage: sshproxy @ # Usage: sshproxy stop function sshproxy() { selectnetworkinterface if [[ $1 == "stop" ]]; then networksetup -setsocksfirewallproxystate "$selected" off ps x | grep "[s]sh -fN -D 5000" | awk '{print $1}' | xargs kill -9 export http_proxy= https_proxy= echo "\n-> Done: proxy is stopped and SSH connection is closed" return fi echo "\n-> Setting socks proxy on network interface '$selected'" ssh -fN -D 5000 $1 networksetup -setsocksfirewallproxy "$selected" localhost 5000 networksetup -setsocksfirewallproxystate "$selected" on export http_proxy=socks5://127.0.0.1:5000 https_proxy=socks5://127.0.0.1:5000 all_proxy=socks5://127.0.0.1:5000 echo "-> Done: proxy is ready" } # Connects to a TOR server of a specified country # Usage: torproxy {ca},{us} function torproxy() { echo "-> Running Tor proxy on 127.0.0.1:9050" echo "ExitNodes $1\nStrictNodes 1\nAutomapHostsOnResolve 1" > /tmp/torrc tor -f /tmp/torrc echo "-> Done: Tor proxy is stopped, config reset" } # Connects to a TOR server of a specified country and opens a new Google Chrome session # Usage: torchromeproxy {ca},{us} function torchromeproxy() { echo "-> Running Tor proxy on 127.0.0.1:9050" echo "-> Opening Google Chrome..." /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=/tmp/chrome --proxy-server=socks5://127.0.0.1:9050 --incognito & # run tor with specified configuration echo "ExitNodes $1\nStrictNodes 1\nAutomapHostsOnResolve 1" > /tmp/torrc tor -f /tmp/torrc tor -f /tmp/torrc echo "-> Done: Tor proxy is stopped, config reset" } # Automatically Starting tmux on SSH function ssht() { SSH_HOST="${@: -1}" tabname "$SSH_HOST" ssh "$@" -t 'tmux ls && exec tmux a || exec tmux new || exec $SHELL -l' } # Usage: echo "Something that you want" | slugify function slugify() { # Transliterate everything to ASCII iconv -t ascii//TRANSLIT \ | tr -d "'" \ | sed -E 's/[^a-zA-Z0-9]+/-/g' \ | sed -E 's/^-+|-+$//g' \ | tr "[:upper:]" "[:lower:]" } # Generates a password and returns hashed values function genpasswd() { passwd=`env LC_CTYPE=C tr -dc 'a-zA-Z0-9-_\$\?' < /dev/urandom | head -c 20`; sha256=`echo $passwd | shasum -a 256`; sha512=`echo $passwd | shasum -a 512`; md5=`md5 -s $passwd | cut -d'=' -f2 | xargs` echo "Raw: $passwd\n\nSHA256: $sha256\nSHA512: $sha512\n\nMD5: $md5"; } # Usage: gitretag function gitretag() { if [ "$1" = "" ]; then echo "missing tag" exit 1 fi git tag -d $1 && git push origin :$1 && git tag $1 && git push origin $1 } # See https://www.iterm2.com/3.3/documentation-scripting-fundamentals.html function iterm2_print_user_vars() { iterm2_set_user_var phpVersion $(php -v | awk '/^PHP/ { print $2 }') iterm2_set_user_var rubyVersion $(ruby -v | awk '{ print $2 }') iterm2_set_user_var nodeVersion $(node -v | awk '{ gsub("v", ""); print $1 }') iterm2_set_user_var goVersion $(go version | awk '{ gsub("go", ""); print $2 }') iterm2_set_user_var mondayVersion $(/usr/local/bin/monday version | awk '{ gsub("v", ""); print $5 }') iterm2_set_user_var kubeContext $(kubectl config get-contexts | grep "*" | awk '{ print $2 }') } # Usage: search function search() { grep -ri $2 $1 } # Usage: searchreplace function searchreplace() { grep -ri $2 $1 | cut -d':' -f1 | xargs sed -i '' "s#$2#$3#g" } # Gets iTunes current track information function itunes_title_script() { osascript -e 'tell application "iTunes" to get the '"$1"' of the current track' } function track() { artist=$(itunes_title_script artist) name=$(itunes_title_script name) echo "$artist - $name" } # Find files and exec commands at them. # $ findexec .coffee cat | wc -l # # => 9762 function findexec() { find . -type f -iname "*${1:-}*" -exec "${2:-file}" '{}' \; } # Count code lines in some directory. # $ loc py js css # # => Lines of code for .py: 3781 # # => Lines of code for .js: 3354 # # => Lines of code for .css: 2970 # # => Total lines of code: 10105 function loc() { local total local firstletter local ext local lines total=0 for ext in $@; do firstletter=$(echo $ext | cut -c1-1) if [[ firstletter != "." ]]; then ext=".$ext" fi lines=`findexec "*$ext" cat | wc -l` lines=${lines// /} total=$(($total + $lines)) echo "Lines of code for ${fg[white]}$ext${reset_color}: ${fg[yellow]}$lines${reset_color}" done echo "${fg[white]}Total${reset_color} lines of code: ${fg[yellow]}$total${reset_color}" } # Returns 2FA code # Usage: otp function otp() { if [ -z $1 ]; then echo echo "Usage:" echo " otp google" echo echo "Configuration: $HOME/.otpkeys" echo "Format: name=key" return 1; fi OTPKEY=$(sed -n "s/${1}=//p" ~/.otpkeys) if [ -z $OTPKEY ]; then echo "$(basename $0): Unknown service name '$1'" return 1; fi oathtool --totp -b $OTPKEY } # Uploads a file to transfer.sh and returns the public URL # Usage: transfer function transfer() { if [ $# -eq 0 ]; then echo -e "No arguments specified. Usage:\necho transfer /tmp/test.md\ncat /tmp/test.md | transfer test.md"; return 1; fi tmpfile=$( mktemp -t transferXXX ); if tty -s; then basefile=$(basename "$1" | sed -e 's/[^a-zA-Z0-9._-]/-/g'); curl --progress-bar --upload-file "$1" "https://transfer.sh/$basefile" >> $tmpfile; else curl --progress-bar --upload-file "-" "https://transfer.sh/$1" >> $tmpfile; fi cat $tmpfile; echo "\n"; rm -f $tmpfile; } # Kills processes that run of a given port number # Usage: killp function killp { lsof -i :$1 | tail -n+2 | awk '{ print $2 }' | xargs kill } # Graph ping between host and a given hostname # Usage: pinggraph function pinggraph { while true; \ do echo '{"ping": '`ping -c 1 $1 | awk -F"=| " 'NR==2 {print $10}'`'}'; \ sleep 0.2; \ done | \ jplot --steps 500 ping } # Graph (using curl and jplot) website response times # Usage: wwwgraph function wwwgraph { while true; \ do curl -s -o /dev/null -w '{"lookup": %{time_namelookup}, "connect": %{time_connect}, "appconnect": %{time_appconnect}, "pretransfer": %{time_pretransfer}, "redirect": %{time_redirect}, "starttransfer": %{time_starttransfer}, "total": %{time_total}}' $1 | \ sed -E 's/([0-9]),([0-9])/\1.\2/g'; \ sleep 1.5; \ done | \ jplot lookup+connect+appconnect+pretransfer+redirect+starttransfer+total } # Graph a process CPU and memory usage # Usage: processgraph (Chrome, node, ...) function processgraph { while true; \ do ps aux | \ grep -E "$1" | \ grep -v grep | \ awk '{ cpu += $3; mem += $4} END {print "{\"cpu\":"cpu",\"mem\":"mem"}"}' | \ sed -E 's/([0-9]),([0-9])/\1.\2/g'; \ sleep 0.2; \ done | \ jplot --steps 600 cpu+mem } # Graph a process CPU and memory usage over SSH # Usage: sshprocessgraph (Chrome, node, ...) function sshprocessgraph { subcommand='ps aux | \ grep -E '\"$2\"' | \ grep -v grep | \ awk '\''{ cpu += $3; mem += $4} END {print "{\"cpu\":"cpu",\"mem\":"mem"}"}'\'' | \ sed -E "s/([0-9]),([0-9])/\1.\2/g"' ssh $1 "while true; \ do $subcommand; \ sleep 0.2; \ done" | \ jplot --steps 600 cpu+mem } # Graph a RabbitMQ queue information # Usage: rabbitgraph function rabbitgraph { while true; \ do curl -s -u $2:$3 $1/api/queues/$4/$5 | \ jq -r '.messages_ready //=0 | .messages_unacknowledged //=0 | .messages //=0 | .consumers //=0 | .message_stats.publish_details.rate //=0 | .message_stats.ack_details.rate //=0 | .message_stats.redeliver_details.rate //=0' | \ jq -r '"{\"ready\":\(.messages_ready), \"unacked\":\(.messages_unacknowledged), \"total\":\(.messages), \"consumers\":\(.consumers), \"publish_rate\":\(.message_stats.publish_details.rate), \"ack_rate\":\(.message_stats.ack_details.rate), \"redeliver_rate\":\(.message_stats.redeliver_details.rate)}"'; \ sleep 0.3; done | \ jplot --steps 1200 ready+unacked+total+consumers+publish_rate+ack_rate+redeliver_rate } # Kubernetes cp (put) on a specific pod # Usage: kcpp context namespace pod-name source dest function kcpp { podName=`kubectl --context $1 -n $2 get pods | grep $3 | cut -d' ' -f1 | head -1` echo_and_run kubectl --context $1 -n $2 cp $4 $podName:$5 } # Kubernetes cp (get) from a specific pod # Usage: kcpg context namespace pod-name source dest function kcpg { podName=`kubectl --context $1 -n $2 get pods | grep $3 | cut -d' ' -f1 | head -1` echo_and_run kubectl --context $1 -n $2 cp $podName:$4 $5 } # Kubernetes exec on a specific pod # Usage: kexec context namespace pod-name function kexec { podName=`kubectl --context $1 -n $2 get pods | grep $3 | cut -d' ' -f1 | head -1` echo_and_run kubectl --context $1 -n $2 exec -it $podName -- ${@:4} } # Forward TCP trafic to a given hostname/port by using an existing Kubernetes pod # Usage: ktcpserver function ktcpserver { podName=`kubectl --context $1 -n $2 get pods | grep $3 | cut -d' ' -f1 | head -1` echo_and_run tcpserver 127.0.0.1 $5 kubectl --context $1 -n $2 exec -i $podName -- nc -v $4:$5 } # Kubernetes port-forward alias that keeps reconnect when failing # Usage: kforward context namespace pod-name ports function kforward { while true; do podName=`kubectl get pods -n $2 --context $1 | grep $3 | head -1 | cut -d' ' -f1` echo_and_run kubectl port-forward --context=$1 -n $2 $podName $4 $5 $6 $7 $8 $9 done } # Usage: kpodname context namespace pod-name function kpodname { kubectl get pods -n $2 --context $1 | grep $3 | head -1 | cut -d' ' -f1 } # ksocatforward context namespace 8025 25 hostname function ksocatforward { echo_and_run kubectl run --context=$1 -n $2 --restart=Never --image=alpine/socat alpine-socat -- -d -d tcp-listen:$4,fork,reuseaddr tcp-connect:$5:$4 echo_and_run kubectl wait --context $1 -n $2 --for=condition=Ready pod/alpine-socat echo "Don't forget to run when finished: kubectl --context $1 -n $2 delete pod/alpine-socat" echo_and_run kubectl port-forward --context $1 -n $2 pod/alpine-socat $3:$4 } # Kubernetes display current image deployed for a pod # Usage: kimage context namespace pod-name function kimage { podName=`kubectl --context $1 -n $2 get pods | grep $3 | cut -d' ' -f1 | head -1` echo_and_run kubectl --context $1 -n $2 describe pod/$podName | grep Image: | cut -d':' -f2- | tr -d ' ' } # Kubernetes display current images deployed for a pod # Usage: kimages context namespace pod-name function kimages { podNames=`kubectl --context $1 -n $2 get pods | grep $3 | cut -d' ' -f1` while IFS= read -r line; do echo -n "-> $line: " kimage $1 $2 $3 done <<< $podNames } # Kubernetes display of pod logs # Usage: klogs context namespace pod-name additional-options function klogs { podName=`kubectl --context $1 -n $2 get pods | grep $3 | cut -d' ' -f1 | head -1` echo_and_run kubectl --context $1 -n $2 logs pod/$podName ${@:4} } function kubernetes_image_diff { kubectl describe pods -n $1 --context $2 | grep Image: | cut -d':' -f2 -f3 | cut -d'/' -f2- | tr -d ' ' > /tmp/$2.diff } # Kubernetes image diff between 2 contexts # Usage: kdiff function kdiff { kubernetes_image_diff $1 $2 kubernetes_image_diff $1 $3 grc diff -d /tmp/$2.diff /tmp/$3.diff rm /tmp/$2.diff /tmp/$3.diff } function pid() { ps aux | grep "$@" | grep -v "grep --color" | cut -d' ' -f2 } # Usage: swap function swap() { mv $1 $1.tmp && mv $2 $1 && mv $1.tmp $2; } # Usage: ddiff function ddiff() { diff $1 $2 | vim -R - } # Usage with piped value: echo | kb # Usage with arguments: kb function kb() { if (( $# == 0 )) ; then echo "scale=2; $( | mb # Usage with arguments: mb function mb() { if (( $# == 0 )) ; then echo "scale=2; $( | gb # Usage with arguments: gb function gb() { if (( $# == 0 )) ; then echo "scale=2; $( # Example: gopprof http://localhost:8001/debug/pprof 5 10 (5 checks and wait 10 seconds each) function gopprof() { PPROF_PATH=${PPROF_PATH:-$HOME/Desktop/pprof} number=${2:-5} interval=${3:-5} rm -rf $PPROF_PATH/png mkdir -p $PPROF_PATH/png for i in {1..$number}; do echo "\n-> iteration $i/$number..." for value in allocs heap goroutine; do echo "dumping: $value..." curl -qs $1/$value > $PPROF_PATH/$value.$i.pprof go tool pprof -png -output $PPROF_PATH/png/$value.$i.png $PPROF_PATH/$value.$i.pprof done sleep $interval done echo "\npprof report generation done, available at: $PPROF_PATH" }