Terminal
Bash
Chaining commands
a && b: dobifasucceeded- not to be confused with
a & b
- not to be confused with
a || b: dobifafailed- these can be chained:
command && echo "success" || echo "fail"
- these can be chained:
a; b: dobregardless of whetherasucceeded
<: use file on right as stdin for command on left|: pipe stdout of command on left to stdin of command on right>: write file on right with stdout of command on left- write to
/dev/nullto discard output
- write to
>>: same as>, but appends&>: redirect stdout & stderr
Background commands
-
command &: run command in the background- to avoid spamming the terminal, redirect output to
/dev/null:command &>/dev/null &
- to avoid spamming the terminal, redirect output to
-
Ctrl+z: suspend (pause) the foreground command
fg: resume suspended command in foregroundbg: resume suspended command in background
-
jobs: list all background and suspended commands -
kill %1: kill job #1 -
disown: disconnect a background command, so it keeps running when the terminal is closed
Substitution
-
$VARNAME: variable substitution- happens in double quotes or when unquoted, but not in single quotes
-
$(command): command substitution (substitutes the result of the command) -
${param}: parameter substitution (substitutes the parameter value) -
!!: repeat the last command entered (ex.sudo !!) -
!$: last argument of the last command (ex. incat foo.txt,foo.txt) -
$?: exit code of the last command0means success, non-zero means failure
Function parameters
- access function parameters using
$1,$2, etc "$@": all parameters- use double quotes to avoid issues with spaces or wildcards
$#: number of parameters given
Control flow & comparisons
- for loop over every file in working directory
for i in *; do echo "$i"; done
- if statement
- the spaces around the condition are important!
- 0 is true and 1 is false (this matches exit codes)
if [[ condition ]]; then
echo "condition 1 passed"
elif [[ condition2 ]]; then
echo "condition 2 passed"
else
echo "both conditions failed"
fi
[[ condition ]]: conditional test (the spaces are important)- 0 is true and 1 is false (matches exit codes)
=: string comparison-eq: numeric comparison (also:-lt,-le,-gt,-ge,-ne)-f: test if something is a file
Wildcards
cp m*.txt scifi/*/matches only foldersfile ^*foo*: exclude files containing foo- requires
setopt extendedglob
- requires
?acts as a single character wildcard- ex.
ls *.?swould list all.js,.ts, etc. files
- ex.
**lists files recursively, ex.ls **/*.json
Hotkeys
- Ctrl+r and Ctrl+s: search command history backwards/forwards
- Ctrl+a: move to beginning of line
- Ctrl+e: move to end of line
- Ctrl+w: delete word
- Ctrl+u: clear from start of prompt to cursor
- Ctrl+k: clear from cursor to end of prompt
- Ctrl+y: undo deleting text
- Ctrl+l: refresh screen
Fish
Basics
set -x VARIABLE SomeValue: export a variableset -Usets a universal variable (persists across sessions)
alias --save name="definition": save alias>?: redirect output to file, but avoid overwriting existing filepsub: lets you save stdout to a temporary file- ex:
diff (sort a.txt | psub) (sort b.txt | psub)
- ex:
- command substitution:
(command)(no$) - access arguments with
$argv[1]instead of$1 - use
$statusinstead of$?for last exit code if type -q command ...: check if command existsset_color: set the text color- supports 3 or 6 digit hex colors, or reserved color names
- use
-cto print reserved color names normalwill reset the color
- use
-o,-i,-u: set bold/italic/underline-b: set the background color
- supports 3 or 6 digit hex colors, or reserved color names
History recall
- Alt+Up Arrow: recall individual arguments
- Alt+s: recall last command with
sudoprefixed
String matching
string match 'word' 'string1' 'string2'...-a: print all matches-e: print entire string, not just match-i: case insensitive-n: report each match as a 1-based start position and length-r: interpret as Perl-style regex- without
-ror-e, the pattern must match the entire string - if the regex contains capturing groups, multiple items will be reported for each match, one for the entire match and one for each capturing group
- automatically sets variables for all named capturing groups
(?<name>expression)- if
-ais used, each variable will contain a list of matches
- if
- without
-v: only print lines that do not match the pattern
Commands
Text search and manipulation
grep
Returns lines that match a word or pattern
grep 'word' filename- filename can also be a directory or pattern, like
.or*.js grep -F(orfgrep) is faster but finds only fixed patterns (not regexp)grep -E(oregrep) handles extended regular expressionsgrep -Puses Perl-style regexps (allows things like look-around assertions)
- filename can also be a directory or pattern, like
-i: case insensitive-w: whole word matches-v: invert match (match only lines that do not contain the word)-R: search directory recursively (ex.grep -R foo ~/bar)-l: show matching filenames-h: do not output file names
Output configuration
- display surrounding lines:
-B(before) and-A(after) - print only what matches pattern:
-o - count number of matches:
-c- prepend line number:
-n
- prepend line number:
awk
Searches files for pattern matches and performs an action based on them
- format:
awk pattern { action } - the entire program (pattern and action) should be quoted
- lines are split into chunks by whitespace, numbered
$1,$2, etc.$0matches the whole line- pass
-F regexpto split byregexpinstead
- action examples
{ print $1 }: print the first whitespace-separated chunklength($0) > 72: print lines longer than 72 characters{ print $2, $1 }: print first two fields in opposite order
- if
patternis missing it will match every line, ifactionis missing it will print all matching lines
sed
sed: modify stdin based on regex- ex.
sed 's/foo/bar/' file.txt - end regex with
/gfor global search
- ex.
wc (word count)
wc: output number of lines, words, and characters (in that order)
cat/less
cat: print file contentsless: show file contents in a scrollable view
head/tail
head -#: output first # linestail -#: output last # lines
sort
sort: sort alphabetically (doesn't modify original)-rto reverse,-hfor numeric sorting
uniq
uniq: filter out duplicate lines if they are adjacent- combine
sortanduniqto remove all duplicates
- combine
nano
- Ctrl+Shift+6: mark text
- Ctrl+k: cut/delete marked text
Files & folders
folderrefers to a folder itself,folder/refers to the contents of the foldercp folder destinationwill copyfolderitself todestination, butcp folder/ destinationwill copy the contents offolder
ls
-1: show results in single column-a: list hidden files-t: sort by modified date
file
file: show information about file
stat
stat -f "%Xf" file.txt: if file is hidden, result will be 8000
find
find dir -type f -name foo*: find all files starting with "foo" in dir (recursive)- use
-type dfor folders (directories)
- use
find dir -name .DS_Store -delete: delete all .DS_Store files in dirfind . -name foo* -exec command: executecommandon all matching files
fd
- faster and friendlier alternative to [[#find]]
- recursively searches the current directory by default
- can pass a directory as the second argument
- can give a regular expression as the pattern
- if called without an argument, lists all files in the current directory recursively
-e EXT: match files with extension EXT-g: match the given pattern exactly-H: include hidden files-I: include gitignored files-E GLOB: exclude files or folders matchingGLOB- create a
.fdignore(like.gitignore) file to always ignore certain files/folders - create a global ignore file at
~/.config/fd/ignore
- create a
-p: match against the full path (ex.fd -p 'foo/bar')-x COMMAND: runCOMMANDagainst each result in parallel- ex. find and unpack all zip files:
fd -e zip -x unzip
- ex. find and unpack all zip files:
-X COMMAND: runCOMMANDonce with all the results as arguments-X rm: remove all files (not folders) that match- run without
-X rmfirst to confirm your choices, or userm -i
- run without
lsof (list open files)
lsof +d dir: shows open files in dirlsof +D dir: shows open files in dir and its subfolderslsof -c Finder: list all files Finder has open
Find process using port
lsof -i :80: find out which processes are using port 80
cp
- move/copy multiple files:
cp a.txt b.txt c/
rsync
- uses modification times to sync only changed files
rsync -av dir1 dir2: copy directory 1 to directory 2-a(archive): sync recursively and preserve symlinks and metadata-v: verbose
rsync -azP dir1 username@host:/path/to/dir2: copy over SSH-z: use compression-P: show progress bar, and allow resuming transfers
- other options:
--exclude=pattern: exclude files matchingpattern-n: dry run
ln
ln -s source target: create a symbolic link fromsourcetotarget
Processes
ps
ps -ef: list running processes-e: include processes from other users-f: show more information
- to filter the list while including headers:
- bash:
ps -ef | { head -1; grep Finder; } - fish:
ps -ef | begin; head -1; grep Finder; end;
- bash:
top
- get CPU usage of a process
-l 2: take 2 samples (CPU usage is based on the delta between samples)- for memory usage, replace
cpuwithmemand omit-l 2
top -stats "command,cpu" -l 2 | grep WindowServer | tail -1
pkill
- send a signal to kill all matching processes by name
- the default signal is
-15which tells the process to exit gracefully- send
-9to kill the process immediately
- send
- the name uses regex matching, to match an exact name use ex.
"^node$"- use the
-fflag to match against the full argument list, ex.pkill -f "node index.js"
- use the
- use
-nor-oto kill the newest or oldest matching process, respectively
pkill -9 "node"
Network
Simple web server
- if npm is installed:
npx serve@latest out -l 3000
- if Python 3 is installed:
python3 -m http.server 3000
ipconfig
Get list of network adapters
ipconfig getiflist
Get network adapter details
- replace
en0with the network adapter name
ipconfig getsummary en0
Get IP address
- replace
en0with the network adapter name
ipconfig getifaddr en0
curl
-v: verbose mode, prints connection steps-X: set request method (GET,POST, etc)-d "body": set the request body-H "header": set a header-s: silent mode, disables progress bar and error messages-sS: disable progress bar but keep error messages
-L: follow redirects-I: fetch headers only
Send a POST request with a JSON body:
curl -X POST -H "Content-Type: application/json" -d '{"name": "Oscar", "species": "cat"}' https://example.com/api/pets
tldr
- pull up cheat sheets with examples for commands
xargs
xargs command: runcommandfor each line in stdin-n 2: limit to the first 2 lines
tmux
tmux: create a new sessiontmux attach: reattach to existing session
Keyboard shortcuts
- Ctrl+b ": split horizontally
- Ctrl+b %: split vertically
- Ctrl+b {arrow}: move focus
- Ctrl+b+{arrow}: resize focused pane
- Ctrl+b x: close pane (y to confirm)
- Ctrl+b d: detach from session
crontab
crontab -l: print crontabcrontab -e: edit crontab (auto reloads on exit)- format:
minute hour dayOfMonth month dayOfWeek command - separate multiple times with commas, ex
1,2,3 - use
*/#to specify an interval, ex.*/20 * * * * commandmeans "every 20 minutes" (without the */ this would mean "on minute 20 of every hour") @reboot commandto run on reboot
- format:
- using
sudoedits a separate crontab forroot
fzf
- lets you interactively filter data from stdin and output the selected item to stdout
SSH Agent
ssh-keygen -l -f <path>: view key fingerprint- to view in MD5 format (colon-delimited) add
-E MD5
- to view in MD5 format (colon-delimited) add
ssh-add <path>: add key to SSH agentssh-add -l: list keys added to SSH agentssh-add -D: remove all keys from SSH agent
node
node --watch script.js: re-run script whenever it changes
npm/yarn
ffmpeg
The build on Homebrew doesn't support webm. Use one of the downloads here instead.
-c: specify codec- use
-codecsto get a list of available codecs - use
-vcodecand-acodecto specify video/audio codecs separately - for webm use
-vcodec libvpx -acodec libvorbis -c copyavoids re-encoding (useful for trimming, changing metadata, etc)
- use
Trim video
ffmpeg -i input.mp4 -ss 00:01:40 -to 00:02:16 -c copy output.mp4: trim to between 1m:40s and 2m:16s
Convert video to audio
ffmpeg -i input.m4a -c:v copy -c:a libmp3lame -q:a 4 output.mp3: convert m4a to mp3 without significant quality loss
Extract frames
ffmpeg -i input.mp4 -ss 00:00:14.435 -vframes 1 out.png: extract one frame from 0h:0m:14sec:435msec to out.pngffmpeg -i input.mp4 frame_%04d.jpg: extract all frames to frame_0001.jpg, frame_0002.jpg, etc
youtube-dl/yt-dlp
--simulate: dry run--match-title keyword: only download items matching keyword-F url: list all available formats-f # url: download video using a format number given by-F
--write-sub --sub-lang en: download subtitles--write-auto-sub: download YouTube automatic subtitles
--add-metadata: add metadata like chapters--embed-thumbnail: embed thumbnail into audio file--merge-output-format mp4: set the output format to mp4--batch-file='videos.txt': download all files invideos.txt(list of URLs, one per line)-f bestaudio[ext=m4a] --add-metadata --embed-thumbnail url: save audio with thumbnail and chapter markers-o "%(playlist_index)s-%(title)s.%(ext)s" <playlist_link>: save a playlist with numbered files--playlist-start 2: start at video 2 in the playlist (1-indexed)--playlist-end 5: end at video 5--playlist-items 1,2,5-7: download certain items
ImageMagick
Input/Output
-
To read from stdin or stdout, replace the input or output filename with
-- Explicit file formats can be provided like this:
png:-
- Explicit file formats can be provided like this:
-
Quick Look result (fish)
qlmanage -c public.image -p (magick convert image.png ... - | psub)
- Select frames from a GIF
magick 'image.gif[0]' image.png
magick 'image.gif[0-3]' image-%d.png # outputs image-0.png thru image-3.png
magick 'image.gif[0,3]' image-%d.png # only frames 0 and 3
Resizing and scaling
- Resize image to fit in a specific size (keeps aspect ratio)
- Percentages can also be used
magick convert image.png -resize 100x100 resized.png
- Stretch the image to the exact size:
-resize 100x100\! - Only shrink larger images:
-resize 100x100\> - Only enlarge smaller images:
-resize 100x100\< - Resize the smallest dimension to fit:
-resize 100x100^- Above plus cropping (like
image-fit: cover):-resize 100x100^ -gravity center -extent 100x100
- Above plus cropping (like
- Other scaling algorithms (replace
-resizewith these):-scale: nearest neighbor-adaptive-resize: can reduce blurring
- To double the image size using Scale2X use
-magnify(with no size argument)
jq
- pipe JSON (ex. from
curl) intojqto pretty-print it jq -s '.[0] * .[1]' --indent 4 old.json patch.json > new.json: recursively merge patch.json into old.json- live preview filters using [[#fzf]]
echo '' | fzf --preview 'jq {q} < filename.json'
Flags
-f path: read filter frompath--indent n: change output indentation-r: output strings without quotes
JSON for examples:
{
"foo": {
"bar": [
{ "name": "Apple", "color": "Red" },
{ "name": "Orange", "color": "Orange" },
{ "name": "Banana", "color": "Yellow" }
]
}
}
List all values for key in array of objects
.[]spreads an array
.foo.bar | .[].name
pandoc
Pandoc can convert to PDF, but not from PDF.
pandoc file.docx -o file.html
macOS-specific
caffeinate
caffeinate: prevent your Mac from sleeping until the process exitscaffeinate -t N: prevent sleep for N seconds
chflags
Hide/unhide files & folders
See [[#stat]] to check if a file/folder is hidden
chflags hidden file.txt
chflags nohidden file.txt
defaults
Remove dock autohide delay
defaults write com.apple.dock autohide-delay -float 0;killall Dock
Dim Dock icons of hidden apps
defaults write com.apple.Dock showhidden -boolean yes; killall Dock
Add a spacer to the Dock
- Applications (left) side:
defaults write com.apple.dock persistent-apps -array-add '{tile-type="spacer-tile";}'; killall Dock
- Documents (right) side:
defaults write com.apple.dock persistent-others -array-add '{tile-data={}; tile-type="spacer-tile";}'; killall Dock
tccutil
Reset app permissions
- Get the app's Bundle ID:
osascript -e 'id of app "Name of App"'
- Reset permissions
- you can replace All with a category name, like
Photos
- you can replace All with a category name, like
sudo tccutil reset All bundle_id
Homebrew
brew leaves: show packages that aren't dependencies of any other installed package-r: only show leaves that were manually installed-p: only show leaves that were installed as dependencies of another package- these can be safely uninstalled, since the package that depended on them is no longer installed
brew cleanup -s: remove unused and outdated cache files
Moom
- adjust spacing for Stage Manager
defaults read com.manytricks.Moom "Grid Spacing: Apply To Edges: Gaps" {0,0,0,75}
PowerShell
$profile: print path to PowerShell profile- edit profile with ex.
code $profile
- edit profile with ex.
explorer .: open Explorer window in current working directory- or
ii .: short forInvoke-Item .
- or
taskkill /F /IM name: kill process matching name (wildcard * can be used)New-Item -ItemType SymbolicLink -Path "dest" -Target "src": create symbolic link to src at dest- must be elevated
-ItemType HardLinkfor hard links
Get-Content urls.txt | ForEach-Object {Invoke-WebRequest $_ -OutFile $(Split-Path $_ -Leaf)}: download list of URLsSplit-Path $_ -Leafgets the last part of the URL as the file name
Environment Variables
Add or append to environment variable
$Env:VariableName = 'value'
$Env:Path += ';C:\Tools'
Get environment variable
Get-Item Env:VariableName
Snippets
Delete hidden macOS files
$theSource = "E:\" # <<<<< insert drive here
Get-Childitem $theSource -Include @("._*", ".DS_Store", ".fseventsd", ".TemporaryItems", ".Trashes", ".Spotlight-V100") -Recurse -Force -ErrorAction SilentlyContinue | Remove-Item -Force -Recurse