Skip to main content


tldr man pages:

List of POSIX commands:

The Art of Command Line:

Shell One-liners:

Oh-heck, a terminal command for when you forget other terminal commands - -

Advanced macOS Command-Line Tools:


zsh is the default shell in macOS since Catalina (10.15, released October 2019) - see

Command history is saved in ~/.zsh_history.

Terminal shortcuts

  • Ctrl + R: Recall
    • Ctrl + R again to see next match
    • Return to execute
    • Ctrl + G to exit without executing
    • Esc to exit but leaving searched command
  • Ctrl + Z: send to the background

Various commands & tips

# set environment variable

# unset environment variable
unset NODE_ENV
  • !!: run the previous command
  • What shell is used: echo $SHELL
  • List all environment variables: printenv. You can also print a specific envar: printenv ANDROID_HOME. (In Linux you can print many, eg printenv ANDROID_HOME PATH, but does not work in macOS.)

Command-line pro tips:

Use curly braces in the command-line to quickly create multiple related files with less typing source:

touch index.{js,css} # creates index.js and index.css
touch {P,H1,H2}.tsx # creates P.tsx, H1.tsx and H2.tsx

You can also use this with npm:

Command substitution

AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)


On your .zshrc or .bash_profile put:

alias l='ls -la'


cd # Go to user's home (~). You can also do 'cd ~'
cd - # Go to the previous directory
cd / # Go to the root directory
cd ~username # Go to the user's root directory


cp -r dir1 dir2 # Recursively


mv file.txt dir


rm -r dir # Recursive is required to delete a directory
rm -r * # Remove all files in current directory, except hidden files
rm -r * .* # Remove all files in current directory, including hidden files

mkdir / rmdir

mkdir -p dir1/dir2/dir3 # With -p if dir1 and dir2 don't exist, it creates them
rmdir -p dir1/dir2/dir3 # With -p it removes dir1 and dir2 too


Either updates the access or modification date of a file, or creates an empty file if it doesn't exist.

Useful to create locks, eg to avoid multiple editing or access. See


echo "Java home is $JAVA_HOME"
echo "something" >> file.txt # Appends
echo "something" > file.txt # OVERWRITES ALL FILE CONTENT
echo -n "abc" # Do not add a newline (at the end)


Backup some file before modifying it, just in case:

cat file.txt > file-backup.txt # Equivalent to 'cp file.txt file-backup.txt'


If the file is big is better use less not cat.

less file.txt

Use /Whatever for searching.


find . -type d -name "build"

find . -type d -name "build" -exec rm -rf {} +

find . -type f -name "*.iml"

find . -type f -name "*.iml" -exec rm -rf {} +

Exclude: find . -type d -name "dist" | grep -v 'node_modules'

See user-friendly alternative fd -


diff -qr Dir1 Dir2

# Exclude directories
diff -qr Dir1 Dir2 --exclude=.git --exclude=node_modules


tree somefolder

To ignore something (eg a folder) use -I <wild-card-pattern>. Eg tree -I node_modules or tree -I venv. There can be multiple -I options.


fc [-e ename] [-lnr] [first] [last]

fc -s [pat=rep] [command]

List recent commands in history: fc -l


If we are running a server at (eg) port 3000 we can do lsof -i :3000 and it will print information about the process that started the server. Doing lsof -t -i :5000 gives the process id. Hence, to kill the process you can do kill -9 $(lsof -t -i :3000).


On macOS, don't bother to try to use the built-in sed, since you get the error 'sed: 1: "eas.json": invalid command code e' all the time. Use GNU sed instead, as advised here. Install it with brew install gnu-sed. Then use gsed instead of sed, or alias it with alias sed='gsed', or add it to the path with PATH="/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH".


Replace value in file:

sed -i "s/THE_VALUE/some_value/" file.txt
sed -i "s/THE_VALUE/$SOME_VAR/" file.txt

s means substitute. See The s Command for more options.

Another example. If we have:

const a = {
version: '0.0.1',

We can do:

sed -i "s|version: '.*'|version: '$VERSION'|" file.ts

sed: -e expression #1, char 19: unknown option to `s'

Beware that if the interpolated value contains a / (eg a URL or a path) it will fail with:

sed: -e expression #1, char 19: unknown option to `s'


Since you can use any delimiter, to fix it do for example:

sed -i "s|THE_VALUE|$SOME_VAR|" file.txt