Terminal
Bash
Chaining commands
a && b
: dob
ifa
succeeded- not to be confused with
a & b
- not to be confused with
a || b
: dob
ifa
failed- these can be chained:
command && echo "success" || echo "fail"
- these can be chained:
a; b
: dob
regardless of whethera
succeeded
<
: 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/null
to 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 command0
means 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 *.?s
would 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 -U
sets 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
$status
instead 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
-c
to print reserved color names normal
will 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
sudo
prefixed
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
-r
or-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
-a
is used, each variable will contain a list of matches
- if
- without
-v
: only print lines that do not match the pattern
Snippets
Get name of frontmost app (macOS)
set result (string match -r '"LSDisplayName"="(.+)"' (lsappinfo info -only name (lsappinfo front)))
echo $result[2]
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 -P
uses 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.$0
matches the whole line- pass
-F regexp
to split byregexp
instead
- 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
pattern
is missing it will match every line, ifaction
is missing it will print all matching lines
sed
sed
: modify stdin based on regex- ex.
sed 's/foo/bar/' file.txt
- end regex with
/g
for 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)-r
to reverse,-h
for numeric sorting
uniq
uniq
: filter out duplicate lines if they are adjacent- combine
sort
anduniq
to remove all duplicates
- combine
nano
- Ctrl+Shift+6: mark text
- Ctrl+k: cut/delete marked text
Files & folders
folder
refers to a folder itself,folder/
refers to the contents of the foldercp folder destination
will copyfolder
itself todestination
, butcp folder/ destination
will 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 d
for folders (directories)
- use
find dir -name .DS_Store -delete
: delete all .DS_Store files in dirfind . -name foo* -exec command
: executecommand
on 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
: runCOMMAND
against 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
: runCOMMAND
once with all the results as arguments-X rm
: remove all files (not folders) that match- run without
-X rm
first 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 fromsource
totarget
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
cpu
withmem
and 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
-15
which tells the process to exit gracefully- send
-9
to kill the process immediately
- send
- the name uses regex matching, to match an exact name use ex.
"^node$"
- use the
-f
flag to match against the full argument list, ex.pkill -f "node index.js"
- use the
- use
-n
or-o
to 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
en0
with the network adapter name
ipconfig getsummary en0
Get IP address
- replace
en0
with 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
: runcommand
for 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 * * * * command
means "every 20 minutes" (without the */ this would mean "on minute 20 of every hour") @reboot command
to run on reboot
- format:
- using
sudo
edits 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
-codecs
to get a list of available codecs - use
-vcodec
and-acodec
to specify video/audio codecs separately - for webm use
-vcodec libvpx -acodec libvorbis
-c copy
avoids 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
-resize
with 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
) intojq
to 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
Dim Dock icons of hidden apps
defaults write com.apple.Dock showhidden -boolean yes; 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 HardLink
for hard links
Get-Content urls.txt | ForEach-Object {Invoke-WebRequest $_ -OutFile $(Split-Path $_ -Leaf)}
: download list of URLsSplit-Path $_ -Leaf
gets 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