Last updated about 5 days ago

Shell (bash | zsh)

Using a default value for a variable

VAL=${<var>:-"<default>"}

The above sets default if var is null or unset. Use only : for skipping null check.

Reuse previous shell command

!!

Example: check git root and cd if proper

git rev-parse --show-toplevel
# /git/root
cd $(!!)

Reinstall xcode-select @MACOS

sudo rm -rf $(xcode-select --print-path) && xcode-select --install

Mount external ntfs hdd @MACOS

  1. brew cask install osxfuse
  2. Reboot
  3. brew install ntfs-3g
  4. Connect hdd
  5. mkdir ~/NTFS
  6. diskutil list (check MS drive num eg disk2s1)
  7. sudo umount /dev/disk2s1
  8. sudo /usr/local/bin/ntfs-3g /dev/disk2s1 ~/NTFS -olocal -oallow_other

Mount an attached block storage (pre-formatted) to instance using fstab

  1. Check currently attached volumes lsblk (ensure attached but not mounted)
  2. Get UUID of volume blkid
  3. Add entry in /etc/fstab UUID=<from above> /mount/point format options
  4. Mount all fstab volumes sudo mount -a
  5. Check currently attached volumes lsblk (ensure mounted)

IMPORTANT! If attaching new block storage, may need to format first

Check size of a directory

du -sh <dir>

where,

Example: Get size of all directories in current directory

du -sh ./*/

Move new files only (do not overwrite if exists)

mv -vn <source> <target>

where,

if/else

if [ <test> ]; then <something>; fi

for command sucess | fail, simply do this (no sq brackets)

if command; then <sucess>; else <fail>; fi

To check if an environment variable exists

if [[ -z $ENV_VAR ]]; then echo "Not exists"; fi;

for loop

for ((expr1;expr2;expr3)); do <command>; done;

Example: Loop from 1 to END

END=5
for ((i=1;i<=END;i++)); do echo $i; done;

for in loop

for <variable> in <list>; do <command>; done

Example: Add all dot files to gitignore

for file in .*; do echo $file >> .gitignore; done

Arrays

An array in shell is within () brackets and looped like so:

arr=("a" "b" "c")

for alph in ${arr[*]}; do echo $alph; done;

Note that on cli, direct $arr works for looping but not in script!

Script strict mode

Ignore the \ in # below, kept for formatting reasons

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

http://redsymbol.net/articles/unofficial-bash-strict-mode/

Find command

find <path> -name "regex" [-exec <another cmd> | -delete]

Example: find and delete all dot files in current directory

find . -name ".*" -delete

as an alternative, fd works as follows

fd -t [d|f] [-HIL] "regex"

Remove duplicate lines from a file

awk '!l[$0]++' file > newfile

if order is not important

sort -u file > newfile # u = unique

Start a background job

nohup <job> < /dev/null > /dev/null 2>&1 & disown

where,

Example: To start mpv as music daemon

nohup mpv --no-audio-display --shuffle ~/Music < /dev/null > /dev/null 2>&1 & disown

Mount Ram as disk

sudo mount -t tmpfs -o size=5g tmpfs /mnt/ramfs

where a new temporary mount point /mnt/ramfs is created with 5 Gigabytes of capacity; to unmount, do

umount /mnt/ramfs

Watch a file for change and run command when changes

while true; do watch -g ls -l <filename> && <cmd>; sleep 5; done

Download a webpage and all it’s linked pages and content

wget -r -l 1 -p -k -H -D domain.com,relateddomain.com http://domain.com/page/in/domain

where,

Generate a random base64 string (May be used as token or password)

head -n1 /dev/urandom | base64

Get all lines except the first:

tail -n+2

Lazy regex quatifier (works in js, not is sed, vim)

Suppose there is a line like so:

"this is some string" "this is another string"

And the aims is to select everything within quotes as a string.

A naive regex would be: /".*"/

But it actually selects everything inside starting from first ” to the end of line ”

To select only the content withing first closing quote, do : /.*?/

That is, add a ? aka a lazy quatifier (as opposed to normal greedy approach)

Add colour to console output (make sure to add Reset at the end after adding colour)

\033[0m : Reset \033[1m : Bold \033[91m : Red \033[92m : Green \033[93m : Blue

const colorize = (...args) => ({
  black: `\x1b[30m${args.join(" ")}`,
  red: `\x1b[31m${args.join(" ")}`,
  green: `\x1b[32m${args.join(" ")}`,
  yellow: `\x1b[33m${args.join(" ")}`,
  blue: `\x1b[34m${args.join(" ")}`,
  magenta: `\x1b[35m${args.join(" ")}`,
  cyan: `\x1b[36m${args.join(" ")}`,
  white: `\x1b[37m${args.join(" ")}`,
  bgBlack: `\x1b[40m${args.join(" ")}\x1b[0m`,
  bgRed: `\x1b[41m${args.join(" ")}\x1b[0m`,
  bgGreen: `\x1b[42m${args.join(" ")}\x1b[0m`,
  bgYellow: `\x1b[43m${args.join(" ")}\x1b[0m`,
  bgBlue: `\x1b[44m${args.join(" ")}\x1b[0m`,
  bgMagenta: `\x1b[45m${args.join(" ")}\x1b[0m`,
  bgCyan: `\x1b[46m${args.join(" ")}\x1b[0m`,
  bgWhite: `\x1b[47m${args.join(" ")}\x1b[0m`,
});

Process SIGnals (man signal)

Using args

# Usage: argsFn 1 2 3 4 5 6 7 8
argsfn() {
  echo "number of args: $#"
  echo "list of args:"; echo $@
  echo "string of args: $*"
  echo "name of script: $0"

  if [ "$#" -lt 3 ]; then
    echo "usage: $0 arg1 arg2 arg3"
    exit
  fi

  echo "first arg: $1"
  echo "second arg: $2"
  echo "third arg: $3"

  shift 3
  echo "rest of the args: $*"
}

Using flags getopt

Get just a filename from whole path

basename -s .txt some/path/to/file.txt

SSHFS (macos)

brew install --cask macfuse
brew tap gromgit/fuse && brew install gromgit/fuse/sshfs-mac
sshfs -V # test if installed
sshfs -o allow_other,default_permissions <server-dir> <local-dir> # follow prompts for permission

On linux, sshfs should be preinstalled, if not just use default package manager

Notifications

# Usage: notify "Hello, World!"
notify() {
  if [[ `uname` == Darwin ]]; then
    osascript -e 'display notification "'$1'"'
  else
    # TODO linux
    # notify "Notification Text"
  fi
}

Mark an MacOS application as safe (bypass Gatekeeper)

xattr -d com.apple.quarantine /path/to/Application.app