Sign in

Julia's Reruns Bot

@b0rk-reruns.jvns.ca
260 followers 1 following 318 posts

This is a bot that I (@b0rk.jvns.ca) made to post reruns of my comics. Posts ~3x/week. Almost all of these are part of zines that you can buy at wizardzines.com, and you can find all of them at wizardzines.com/comics.

PostsRepliesMedia
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 03/10/2026
subqueries permalink: wizardzines.com/comics/subqueries from our zine Become a SELECT star!: wizardzines.com/zines/sql
Some questions can't be answered with one Simple SQL query.

For example, this query finds owners who have named their dogs popular names: ("boring" owners :))

dogs:

| owner    | name      |
|
050
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 01/10/2026
command line arguments permalink: wizardzines.com/comics/command-line…

### every process has command line arguments
`$ ls 1 /usr/bin`   
(`ls`, `-l`, and `usr` are arguments!)

### they're passed to the program as an array
example from Python:
```
import sys 
print(sys.argv)
```
`['test.py', 'file.txt' ]`

### arguments can be any sequence of bytes
`$ python program.py ♥`   
(emoji are totally allowed!)

### the first argument is the executable's name
```
[
'ls'
'-1',
'/usr/bin/'
]
```
(`ls` is the executable name)

### the total length of the arguments is limited
you can find the limits on your system with `xargs -show-limits`   
It's usually ~2MB

### you can decide how you parse arguments
- `-flag`: single dash!
- `--flag`: 2 dashes!
- `♥♥flag`: weird emoji scheme that will be very annoying to use!
050
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 29/09/2026
clock_gettime permalink: wizardzines.com/comics/clock-gettime
### programs can be slow for a lot of reasons

Illustration of two programs, each represented by a box with a smiley face.
 
program 1: I'm waiting for a database query, you?   
program 2: I'm using SO MUCH CPU!

### it's not obvious when a program is using CPU
Illustration of a stick figure with curly hair, looking unhappy.

person: my webserver took 6 seconds to respond to that request! why?

### panel 3
person: how can I tell how much CPU time was used in this part of my code?

### clock-gettime 
clock-gettime is a system call. It can tell you how much CPU time your process/thread used since it started.

### how to track CPU time
1. run clock-gettime
2. do the thing (eg handle a HTTP request) 
3. run clock-gettime
4. subtract!

### this trick works when You have 1 HTTP request per thread at a time
Illustration of Ruby and node.js, each represented by a box with a smiley face.

Ruby: I can use clock-gettime  
node.js: doesn't work for me, I have an event loop!
041
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 27/09/2026
assembly permalink: wizardzines.com/comics/assembly
040
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 25/09/2026
CPU scheduling permalink: wizardzines.com/comics/cpu-scheduli…
0111
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 23/09/2026
inside .git permalink: wizardzines.com/comics/inside-git from our zine How Git Works: wizardzines.com/zines/git
### `HEAD`
`HEAD` is a tiny file that just contains the name of your current branch 

`.git/HEAD`    
`ref: refs/heads/main`

`HEAD` can also be a commit ID, that's called "detached `HEAD` state"

### branches
a branch is stored as a tiny file that just contains 1 commit ID. It's stored in a folder called `refs/heads`. 

`7622629` - (actually 40 characters)

tags are in `refs/tags`, the stash is in `refs/stash`

### commit
a commit is a small file containing its parent(s), message, tree, and author 

`.git/objects/7622629` 
```
tree c4e6559 
parent 037ab87 
author Julia <x@y.com> 1697682215 
committer Julia <x@y.com> 1697682215 
commit message goes here 
```
these are compressed, the best way to see objects is with `git cat-file -p HASH`

### trees
trees are small files with directory listings. The files in it are called "blobs"

`.git/objects/c4e6559`
```
100644 blob e351d93 404.html 
100644 blob cab4165 hello.py
040000 tree 9de29f7 lib
```
the permissions here LOOK like unix permissi
060
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 21/09/2026
git discussion bingo permalink: wizardzines.com/comics/git-discussi… from our zine How Git Works: wizardzines.com/zines/git
A grid of boxes, like a bingo card, with the following text in them:

- WTF is detached HEAD state
- just use magit
- subversion was so much worse
- rewriting history is bad
- I just do not care how git works
- I hate git
- git is a directed acyclic graph
- I only know 5 commands
- just spend 15 minutes learning git's internals
- content addressed storage
- git's design is so elegant
- you have to understand the linux kernel dev workflow
- a branch is just a pointer to a commit
- something about "porcelain"
- subversion was better
- I've used git for 10 years and I have no idea how it works
- mercurial is better
- git is not github
- the CLI is badly designed
- merge sucks, only use rebase
- something about Linus Torvalds
- commits are immutable snapshots
- you should just read Pro Git
- rebase sucks, only use merge
- I just delete my git repo if I mess it up
0122
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 19/09/2026
fixing diverged remotes permalink: wizardzines.com/comics/fixing-diver… from our zine How Git Works: wizardzines.com/zines/git
### ways to reconcile two diverged branches

Illustration of a sequence of boxes joined with lines. The first box is a star, the second box is a heart, and then it branches out into two boxes, one with a hash symbol and one with a squiggle. Hash symbol box is labelled “local main” and squiggle box is labelled “remote main”

- combine the changes from both with (1) rebase or (2) merge!
- throw out your local changes (3) after breaking your local branch!
- throw out the remote changes (4) to get rid of something you accidentally pushed (be REAL careful with this one) 

### reasons to throw away changes

- I’ll throw away local changes if I accidentally committed to `main` instead of a new branch
- I’ll throw away remote changes if I want to amend a commit after pushing it, and I’m the only one working on that branch 

### 1. rebase
```
git pull --rebase
git push
```
Illustration of four boxes (star, heart, squiggle, hash) in a straight line, labelled “local main” and “remote main”

Many
040
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 17/09/2026
every git jargon permalink: wizardzines.com/comics/every-git-ja… from our zine How Git Works: wizardzines.com/zines/git
### config
```
.git/config
hook
.gitconfig
alias
global
local
```

### history
```
log
blame
bisect
diff
```

### commit
```
commit
checkout
tree-ish
show
patch
apply
remotes
restore
```

### staging area
```
index
staged
cached
grep
add
status
staging area
```

### branches
```
HEAD
refs/heads/main
detached HEAD state
head
HEAD^, HEAD~, HEAD^^
reference
symbolic reference
reset
tag
main
master
reflog
..
...
```

### other features
```
stash
worktree
subtree
submodule
revert
```

### merging
```
merge
conflict
rebase
interactive rebase
fast forward merge
cherry-pick
squash
ours/theirs
```

### remotes
```
upstream
downstream
push
pull
fetch
clone
fork
remote
refspec
origin
```
020
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 15/09/2026
your domain's authoritative nameservers permalink: wizardzines.com/comics/your-domains… from our zine How DNS Works: wizardzines.com/zines/dns
### when you register a domain, your registrar runs your authoritative nameservers by default
your registrar, represented by a box with a smiley face wearing a crown: I'm taking care of your DNS!

You can change your nameservers in your registrar's control panel.


### LOTS of services can be your authoritative nameserver
your registrar: I can manage your DNS records!  
AWS, also represented by a box with a smiley face wearing a crown: me too!  
shopify, also also represented by a box with a smiley face wearing a crown: me three!

Nonplussed stick figure with curly hair: ok chill I only need one of you to do it

### how to find your domain's nameservers
```
$ dig +short NS neopets.com 
ns-42.awsdns-05.com. 
ns-1191.awsdns-20.org.
```
`neopets.com` is using AWS's nameservers right now

### how to change your nameservers
1. Copy your DNS records to the new nameservers (use dig to check that it worked) 2. On your registrar's website, update your nameservers 
3. Wait 48 hours
4. Delete the
011
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 13/09/2026
why DNS updates are slow: caching permalink: wizardzines.com/comics/why-dns-upda… from our zine How DNS Works: wizardzines.com/zines/dns
### You might have heard that DNS updates need time to "propagate".
What's actually happening is that there are old cached records which need to expire.

### DNS records are cached in many places
- browser caches
- DNS resolver caches 
- operating system caches

google.com, represented by a box with a smiley face: my DNS records are cached on billions of devices!

### let's see what happens when you update an IP
bananas.com A▾   
300 [changed to] 60  
1.2.3.4 [changed to] 5.6.7.8
  
beware: even if you change the TTL to 60s, you still have to wait 300 seconds for the old record to expire

### 30 seconds later... 
(you go to bananas.com in your browser) 

Illustration of a resolver, represented by a box with a smiley face holding a magnifying glass, and a browser, represented by the Firefox logo of a fox wrapped around a globe

browser: hey what's the IP for bananas.com?   
resolver, thinking: let's check my cache for bananas.com... found it!!    
resolver: it's 1.2.3.4!

### 400 second
030
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 11/09/2026
the root nameservers permalink: wizardzines.com/comics/root-nameser… from our zine How DNS Works: wizardzines.com/zines/dns
### every DNS resolver starts with a root nameserver
Illustration of a conversation between a resolver, represented by a box with a smiley face holding a magnifying glass, and a root nameserver, represented by a box with a smiley face wearing a stack of crowns. 

resolver: what's the IP for example.com?   
root nameserver: You should ask a `.com` nameserver! They're at `a.gtld-servers.net, b....`

### root nameserver IP addresses almost never change
`a.root-servers.net`'s IP (`198.41.0.4`) hasn't changed since 1993. DECADES ago!

### there are thousands of physical root nameservers, but only 13 IP addresses 
Each IP refers to multiple physical servers, you'll get the one closest to you. (this is called "anycast")

There's a map at https://root-servers.org

### if they didn't exist, resolvers wouldn't know where to start
resolver, distressed: I need an IP address of an initial server to query, and I can't use DNS to get that IP!

### every resolver has the root IPs hardcoded in its sour
050
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 09/09/2026
the DNS hierarchy permalink: wizardzines.com/comics/dns-hierarchy from our zine How DNS Works: wizardzines.com/zines/dns
### there are 3 main levels of authoritative DNS servers
root (wearing 3 crowns): I'm in charge of EVERYTHING   
.com nameserver (wearing 2 crowns): I'm in charge of all domains ending in `.com`   
example.com nameserver (wearing 1 crown): I'm in charge of all domains ending in `example.com`

### the root nameserver delegates
what's the IP for example.com?   
root: I am not concerned with petty details like that. Here's the address of the .com nameserver.

### the .com nameserver also delegates
what's the IP for example.com?   
.com nameserver: I am not concerned with petty details like that either. Here's the address of the example.com nameserver

### the example.com nameserver actually answers your questions
what's the IP for example.com?   
example.com nameserver: 93.184.216.34! 

### this design lets DNS be decentralized
example: for my domain `jvns.ca`

root (ICANN controls this!)   
delegates to  
.ca nameserver (Canada controls this!)   
delegates to    
jvns.ca nameserver (I co
065
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 07/09/2026
sort & uniq permalink: wizardzines.com/comics/sort-uniq from our zine Bite Size Command Line!: wizardzines.com/zines/bite-size-com…
### `sort` sorts its inputs 
`$ sort name.txt`

the default sort is alphabetical

### `sort -n`: numeric sort
`sort order` (sad face):
- 12
- 15000
- 48 
- 6020
- 96

`sort -n` order (happy face):
- 12
- 48
- 96
- 6020 
- 15000

### `sort -h`: human sort
`sort -n` order (sad face):
- 15 G
- 30 M
- 45 K
- 200 G

`sort -h` order (happy face):
- 45 K 
- 30 M
- 15 G
- 200 G

useful example: `du -sh * | sort -h`

### `uniq` removes duplicates
before:
- a
- b
- b
- a
- c
- c

after: 
- a
- b
- a
- c

(notice there are still 2 'a's! uniq only uniquifies adjacent matching lines

### `sort` + `uniq` = (heart)
Pipe something to `sort | uniq` and you'll get a deduplicated list of lines! `sort -u` does the same thing.

before `sort -u` (or `sort | uniq`):
- b
- a 
- b
- a

after:
- a
- b

### `uniq -c`
counts each line it saw.

Recipe: get the top 10 most common lines in a file:
```
$ sort foo.txt
   | uniq -c
   | sort -n
   | tail -n 10
```

happy little stick figure with curly hair: I use this
162
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 05/09/2026
sed permalink: wizardzines.com/comics/sed from our zine Bite Size Command Line!: wizardzines.com/zines/bite-size-com…
### sed is most often used for replacing text in a file
`$ sed s/cat/dog/g file.txt`  
"cat"can be a regular expression

### change a file in place. with -i
person: in GNU sed it's -i, in BSD sed, -i SUFFIX confuses me every time.

### Some more sed incantations...

### sed -n 12 p 
print 12th line
-n suppresses output so only what you print with 'p' gets printed

### sed 5 d 
delete 5th line

### sed /cat/d 
delete lines matching /cat/

### sed -n 5,30 p
print lines 5-30

### sed s+cat/+dog/+ 
('+' can be any character)   
Use + as a regex delimeter  
person: way easier than escaping /s like s/cat\//dog\//!

### sed -n s/cat/dog/p 
only print changed lines.

### sed G
double space a file (good for long error lines)

### sed /cat la dog' 
append 'dog' after lines containing 'cat'

### sed 'i 17 panda" 
insert "panda" on line 17
041
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 01/09/2026
ps permalink: wizardzines.com/comics/ps-1 from our zine Bite Size Command Line!: wizardzines.com/zines/bite-size-com…
### `ps`

`ps` shows which processes are running

I usually run `ps` like this:
`$ ps aux`

u means include username column   
a+x together show all processes

(`ps -ef` works too)

### `w`
is for wide. `ps auxwww` will show all the command like args for each process

### `e`
is for environment. `ps auxe` will show the environment vars!

### wchan
you can choose which columns to show with `ps` (`ps -eo...`)

One cool column is '`wchan`', which tells you the name of the kernel function if the process is sleeping.

try it:   
`$ ps -eo user,pid,wchan,cmd`

### process state
Here's what the letters in `ps`'s STATE column mean:

- `R`: running
- `S/D`: asleep
- `Z`: zombie
- `l`: multithreaded
- `+`: in the foreground

### `f`
is for "forest" :) `ps auxf` will show you an ASCII art process tree!

`pstree` can display a process tree, too.

### `ps` has 3 different sets of command line arguments
(broken heart)

1. UNIX (1 dash)
2. BSD (no dash)
3. GNU (2 dashes)

you can write monstrosities
041
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 28/08/2026
ip permalink: wizardzines.com/comics/ip-1 from our zine Bite Size Networking!: wizardzines.com/zines/bite-size-net…
### `ip`
(Linux only)  
lets you view + change network configuration

`$ ip OBJECT COMMAND`

(`OBJECT`: addr, link, neigh, etc. `COMMAND`: add, show, delete, etc.)

### `ip addr list`
shows ip addresses of your devices. Look for something like this:

```
2: eth0:
   link/ether 3c:97...
   inet 192.168.170/24
```

### `ip route list`
displays the route table.

```
default via 192.168.1.1
169.240.0.0/16 dev docker0
```
(`192.168.1.1` is my router)

to see all route tables:   
`$ ip route list table all`

### change your MAC address
good for cafes with time limits (little devil face)

```
$ ip link set wlan0 down
$ ip link set eth0 address
  3c:a9:f4:d1:00:32
$ ip link set wlan0 up
$ service network-manager
  restart 
```
(or whatever you use)

### `ip link`
network devices! (like `eth0`)

### `ip neigh`
view/edit the ARP table

### `ip xfrm`
is for IPsec

### `ip route get IP`
what route will packets with `$IP` take?

### `--color`
pretty colourful output!

### `--brief`
show a summary
020
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 26/08/2026
every Linux networking tool I know permalink: wizardzines.com/comics/every-linux-… from our zine Bite Size Networking!: wizardzines.com/zines/bite-size-net…
### ping
"are these computers even connected?"

### curl
make any HTTP request you want

### httpie
like curl but easier ("http get")

### wget
download files

### tc
on a linux router, slow down your brother's internet (and much more)

### dig/nslookup
what's the IP for that domain? (DNS query)

### whois
is this domain registered?

### ssh
secure shell 💙

### scp
copy files over a SSH connection

### rsync
copy only changed files (works over SSH)

### ngrep
grep for your network

### tcpdump
"show me all packets on Port 80!"

### wireshark
look at those packets in a GUI

### tshark
command line super powerful packet analysis

### tcpflow
capture & assemble TCP streams

### ifconfig
"what's my IP address?"

### route
view & change the route table

### ip
replaces ifconfig, route, and more!

### arp
see your ARP table

### mitmproxy
spy on SSL connections your programs are making

### nmap
in ur network scanning ur ports

### zenmap
GUI for nmap

### p0f
identify OS of hosts connecting
1187
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 24/08/2026
ethtool permalink: wizardzines.com/comics/ethtool from our zine Bite Size Networking!: wizardzines.com/zines/bite-size-net…
### ethtool is for people who need to manage physical networks

server, represented by a sad rectangle: why no internet??   
smiling stick figure with short curly hair: oops! it would help if you ethernet cable was plugged in!

### `ethtool eth0`
(name of network interface)

this tells you:
- is it even connected? ("link detected")
- speed
- lots more

### `--show-offload --offload`
your network card can do a lot for you! Like computing checksums. This is called "offloading". This lets you see/change configured offloads.

### `--identify INTERFACE`
blink the light on the ethernet port. good if you have multiple ports! and cute. (heart)

### `-S INTERFACE`
show statistics like bytes sent. works for wifi interfaces too.

### `-s`
change speed/duplex/other settings of an interface.

`$ ethtool - eth0 speed 100`

### `-i INTERFACE`
show firmware info

### `iw dev wlan0 link`
ethtool is mostly for Ethernet.

To see the speed (and more) of a wireless connection, use iw.
063
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 22/08/2026
using HTTP APIs permalink: wizardzines.com/comics/http-apis from our zine HTTP: Learn your browser's language!: wizardzines.com/zines/http
Lots of services (Twitter! Twilio! Google!) let you use them by sending them HTTP requests. If an HTTP API doesn't come with a client library, don't be scared! You can just make the HTTP requests yourself. Here's what you need to remember:

### Set the right `Content—Type` header
Often you'll be sending a POST request with a body, and that means you need a `Content—Type` header that matches the body.

The 2 main options are:
- `application/json` (JSON!)
- `application/x-www-form-urlencoded` (same as what an HTML form does)

If you don't set the `Content—Type`, your request won't work.

Smiling stick figure with short curly hair: a common error is to try to send POST data as one content type (like JSON) when it's actually another (like application/x-www-form-urlencoded)

### Identify yourself
Most HTTP APIs require a secret API key so they know who you are.
Here's how that looks for the Twilio API:
```
curl
https://api.twilio.com/2010-04-01/Accounts/ACCOUNT_ID/Messages.json
    -H "Cont
062
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 20/08/2026
the same-origin policy permalink: wizardzines.com/comics/same-origin-… from our zine HTTP: Learn your browser's language!: wizardzines.com/zines/http
011
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 18/08/2026
the most important HTTP request headers permalink: wizardzines.com/comics/request-head… from our zine HTTP: Learn your browser's language!: wizardzines.com/zines/http
These are the most important request headers:

### Host
The domain  
The only required header.   
`Host: examplecat.com`

### User-Agent
name + version of your browser and OS   
`User-Agent: curl 7.0.2`

### Referer
(yes, it's misspelled!)   
website that linked or included the resource   
`Referer: http://examplecat.com`

### Authorization
eg a password or API token   
base64 encoded user: password  
`Authorization: Basic YXZ`

### Cookie
send cookies the server sent you earlier   
keeps you logged in   
`Cookie: user=b0rk`

### Range
lets you continue downlats ("get bytes 100-200")   
`Range: bytes=100-200`

### Cache-Control
"max-age=60"
means cached responses must be less than 60 seconds old   

### If-Modified-Since
only send if resource was modified after this time   
`If-Modified-Since: Wed, 21 Oct...`

### If-None-Match
only send if the ETag doesn't match those listed   
`If-None-Match: "e7ddac"`

### Accept
MIME type you want the response to be   
`Accept: image/png`

### Acce
062
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 16/08/2026
http status codes permalink: wizardzines.com/comics/status-codes from our zine HTTP: Learn your browser's language!: wizardzines.com/zines/http
Every HTTP response has a status code.
browser, optimistically: `GET /cat.png` (request)   
server, sadly: 404 not found (404 is the status code!)

There are 50ish status codes but these are the most common ones in real life:

2xxs mean ★Success★
- 200 OK

3xx s aren't errors, just redirects to somewhere else
- 301 Moved Permanently
- 302 Found: temporary redirect
- 304 Not Modified: the client already has the latest version, "redirect" to that

4xx errors are generally the client's fault: it made some kind of invalid request
- 400 Bad Request
- 403 Forbidden: API key/OAuth/something needed
- 404 Not Found: we all know this one :)
- 429 Too Many Requests:  you're being rate limited

5xx errors generally mean something's wrong with the server.
- 500 Internal Server Error: the server code has an error
- 503 Service Unavailable: could mean nginx (or whatever proxy) couldn't connect to the server
- 504 Gateway Timeout: the server was too slow to respond
130
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 12/08/2026
the OOM killer permalink: wizardzines.com/comics/oom-killer
032
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 10/08/2026
terminals permalink: wizardzines.com/comics/terminals
050
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 08/08/2026
segmentation faults permalink: wizardzines.com/comics/segfaults
040
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 04/08/2026
unix permissions permalink: wizardzines.com/comics/unix-permiss… from our zine Bite Size Linux!: wizardzines.com/zines/bite-size-lin…
### There are 3 things you can do to a file

**r**ead **w**rite e**x**ecute

### `ls -l file.txt` shows you permissions.
Here's how to intepret the output:

`rw- rw- r-- bork staff`

the first `rw-` means bork (user) can read & write   
the second `rw-` means staff (group) can read & write   
`r--` means ANYONE can read


### File permissions are 12 bits

The first digit is `setuid`, the second digit is `setgid`, the third digit is `sticky`   
`110` (user) `110` (group) `100` (all)

For files:   
r = can read  
w = can write   
x = can execute   

For directories, it's approximately:   
r = can list files  
w = can create files   
x = can cd into & access files   

### 110 in binary is 6
So `rw-`   
= 110   
= 6   

`r--`   
= 100   
= 4   

`r-- `  
= 100    
= 4   

`chmod 644 file.txt` means change the permissions to `rw- r-- r--`: simple!

### setuid affects executables
`$ls -l /bin/ping`
`rws r-x r-x root root`

(the s means ping always runs as oot)

`setgid` does 3 different unre
074
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 02/08/2026
unix domain sockets permalink: wizardzines.com/comics/unix-domain-… from our zine Bite Size Linux!: wizardzines.com/zines/bite-size-lin…
### unix domain sockets are files


```
$ file mysock.sock
socket
```
the file's permissions determine who can send data to the socket.

### they let 2 programs on the same computer communicate


Docker uses Unix domain sockets, for example!

process: GET/container (HTTP request)
Docker: Here you go!

### There are 2 kind of unix domain sockets

- `stream`: Like TCP! Lets you send a continuous stream of bytes
- `datagram`: Like UDP! Let you send discrete chunks of data

### advantage 1
Lets you use file permission to restrict access to HTTP/database services!

`chmod 600 secret.sock`

This is why Docker uses a unix domain socket. (lock icon)

evil process: run evil container   
Linux, nonplussed: permission denied

### advantage 2
UDP sockets aren't always reliable (even on the same compute).

unix domain datagram sockets ARE reliable! And they won't reorder packets!

Process: I can send data and I KNOW it'll arrive

### advantage 3
You can send a file descriptor over a unix domain soc
0113
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 29/07/2026
anatomy of a HTTP response permalink: wizardzines.com/comics/anatomy-http… from our zine HTTP: Learn your browser's language!: wizardzines.com/zines/http
### HTTP responses have:
- a status code (200 OK! 404 not found!)
- headers
- a body (HTML, an image, JSON, etc)

### Here's the HTTP response from `examplecat.com/cat.txt`:
```
HTTP/1.1 200 OK
status
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Content-Length: 33
Content-Type: text/plain; charset=UTF-8 Date: Mon, 09 Sep 2019 01:57:35 GMT
Etag: "ac5affa59f554a1440043537ae973790-ssl"
Strict-Transport-Security: max-age=31536000
Age: 0
Server: Netlify
[ASCII image of a cat, labelled "cat!" with a smiley face]
```
The first line, `HTTP/1.1 200 OK` is the status code. "200" is the status.   

The lines from `Accept-Ranges` to `Server` are the headers.

The cat picture is the body.

### There are a few kinds of response headers:

- when the resource was sent/modified:
```
Date: Mon, 09 Sep 2019 01:57:35 GMT
Last-Modified: 3 Feb 2017 13:00:00 GMT
```

- about the response body:
```
Content-Language: en-US 
Content-Length: 33
Content-Type: text/plain; charset=UTF-8
Content-Encoding: g
0102
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 27/07/2026
TLS certificates permalink: wizardzines.com/comics/certificates from our zine HTTP: Learn your browser's language!: wizardzines.com/zines/http
To establish an HTTPS connection to examplecat.com, the client needs proof that the server is `examplecat.com`.

Browser, represented by the Firefox logo: hey I want examplecat.com

Server, represented by a box with a smiley face: here's proof that I'm examplecat.com.

(the proof is called a certificate.)

A TLS certificate has:
- a set of domains it's valid for (eg `examplecat.com`)
- a start and end date (example: July 1 2019 to Oct 1 2019)
- a secret private key that only the server has (this is the only secret part, the rest is public)
- a public key to use when encrypting
- a cryptographic signature from someone trusted

A box that reads "wizardzines.com, Jul 1 - Oct 1 2019, <public key> with a logo that says Let's Encrypt Approved"

The trusted entity that signs the certificate is called a Certificate Authority (CA) and they're responsible for only signing certificates for a domain for that domain's owner.

smiling stick figure with short spiky hair: will you sign this certificat
063
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 23/07/2026
HTTP/2 permalink: wizardzines.com/comics/http2 from our zine HTTP: Learn your browser's language!: wizardzines.com/zines/http
HTTP/2 is a new version of HTTP. Here's what you need to know:

### A lot isn't changing
All the methods, status codes, request/response bodies, and headers mean exactly the same thing in HTTP/2.

before (HTTP/1.1):
```
method: GET  
path: /cat.gif  
headers:
- Host: examplecat.com  
- User-Agent: curl  
``` 

after (HTTP/2):
```
method: GET  
path: /cat.gif  
authority: examplecat.com  
headers:  
- User-Agent: curl
```

one change:  
Host header => authority

#### HTTP/2 is faster
Even though the data sent is the same, the way HTTP/2 sends it is different. The main differences are:
- It's a binary format (it's harder to ```tcpdump``` traffic and debug)
- Headers are compressed
- Multiple requests can be sent on the same connection at a time

before (HTTP/1.1):  
→ request 1  
response 1 ←  
→ request 2  
response 2 ←  

after (HTTP/2):  
→ request 1  
→ request 2  
response 2 ←  
response 1 ← (out of order is ok)   
(one TCP connection)  

All these changes together mean that HTTP/2
060
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 21/07/2026
shellcheck permalink: wizardzines.com/comics/shellcheck from our zine Bite Size Bash!: wizardzines.com/zines/bite-size-bash
### shellcheck finds problems with your shell scripts
`$ shellcheck my-script.sh`
shellcheck: oops, you can't use in an `if [ ... ]`!

### it checks for hundreds of common shell scripting errors
shellcheck: hey, that's a bash- only feature but your script starts with `#!/bin/sh`

### every shellcheck error has a number (like "SC2013")
and the shellcheck wiki has a page for every error with examples! I've learned a lot from the wiki.

### it even tells you about misused commands
shellcheck: hey, it looks like you're not using `grep` correctly here   
person: wow I'm not! thanks!

### your text editor probably has a shellcheck plugin
shellcheck: I can check your shell scripts every time you save!

### basically, you should probably use it
bash has too many weird edge cases for me to remember, I love that shellcheck can help me out!
040
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 19/07/2026
shell script arguments permalink: wizardzines.com/comics/shell-argume… from our zine Bite Size Bash!: wizardzines.com/zines/bite-size-bash
### panel 1:  a script's arguments are in `$1`, `$2`, `$3`, etc

```
./script.sh panda banana
```

`$1` is `"panda"` and `$2` is `"banana"`


### panel 2:  arguments are great for making simple scripts

Here's a 1-line `svg2png` script that I use to convert SVGs to PNGs:

```
#!/bin/bash
inkscape "$1" -b white --export-png="$2"
```

I run it like this:

```
$ svg2png old.svg new.png
```

(arrow pointing to `"$2"`: "always quote your variables!")

### panel 3:  get all the arguments with `"${@}"`

```
ls --color "${@}"
```


### panel 4: you can loop over arguments

```
for i in "${@}"
do
    echo "$i"
done
```


### panel 5: 1 line shell scripts are great

person: "I can write a tiny script so I don't have to remember a long command!"
050
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 17/07/2026
non-POSIX features permalink: wizardzines.com/comics/bashisms from our zine Bite Size Bash!: wizardzines.com/zines/bite-size-bash
### some bash features aren't in the POSIX spec


Illustration of a smiling stick figure with curly hair.

Person: here are some examples! These won't work in POSIX shells like `dash` and `sh`.

### arrays
POSIX shells only have one array: `$@` for arguments

### [[ $DIR=/home/*]]
POSIX alternative: match strings with `grep`

### [[ ... ]]
POSIX alternative:
`[ ... ]`

### diff <(./cmd1) <./cmd2)
this is called "process substitution", you can use named pipes instead

### the local Keyword
in POSIX shells, all variables are global

### for ((i=0; i <3; i++))
`sh` only has for `x` in ... loops, not C-style loops

### a. {png, svg}
you'll have to type
`a.png a.svg`

### {1..5}
POSIX alternative:   
`$(seq 1 5)`

### $'\n'
POSIX alternative:   
`$(printf "\n")`

### ${var//search/replace}
POSIX alternative: 
pipe to `sed`
061
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 15/07/2026
environment variables permalink: wizardzines.com/comics/environment-… from our zine Bite Size Bash!: wizardzines.com/zines/bite-size-bash
### panel 1:  every process has environment variables

how to see any process's environment variables on Linux:

```
cat /proc/$PID/environ | tr '\0' '\n'
```

### panel 2: shell scripts have 2 kinds of variables

1. environment variables
2. shell variables

unlike in most languages, in shell you access both of these in the exact same way: `$VARIABLE`


### panel 3: export sets environment variables

```
export ANIMAL=panda
```

`export ANIMAL=panda` means that every child process will have `ANIMAL` set to `panda`

### panel 4: child processes inherit environment variables

this is wy the variables set in your `.bash_profile` work in all programs you start from the terminal. They're all child processes of your bash shell!


### panel 5: shell variables aren't inherited

```
var=panda
```

in this example, `$var` only gets set in this process, not in child processes

### panel 6: you can set environment variables when starting a program

Illustration of a smiling stick figure with curly
011
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 13/07/2026
xargs permalink: wizardzines.com/comics/xargs from our zine Bite Size Command Line!: wizardzines.com/zines/bite-size-com…
### xargs takes white space separated strings from stdin and converts them into command-line arguments
```
$ echo "/home /tmp" 
| xargs ls 
```
will run `ls /home/tmp`

### this is useful when you want to run the same command on a list of files!
- delete (`xargs rm`)
- combine (`xargs cat`)
- search (`xargs grep`)
- replace (`xargs sed`)

### how to replace "foo" with "bar" in all .txt files:
```
find. -name '*.txt' | 
xargs sed -i s/foo/bar/g
```

### how to lint every Python file in your Git repo:
```
git ls-files | grep pyl 
xargs pep8
```
### if there are spaces in your filenames "my day.txt" xargs will think it's 2 files 
""my" and "day.txt"
fix it like this:  
```
find -print0 |  
xargs -0 COMMAND
```
### more useful xargs options
`-n 1` (max-args): makes xargs run a separate process max-args for each input  
`-P` (capital P, max-procs): is the max number of parallel processes xargs will start
040
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 11/07/2026
top permalink: wizardzines.com/comics/top from our zine Bite Size Command Line!: wizardzines.com/zines/bite-size-com…
### top
a live-updating summary of the top users of your system's resources:

sad little stick person: who's using all my memory   
top: chrome, obv!

let's explain some numbers in top!

### load average
3 numbers that roughly reflect demand for your CUs on the system in the last 1, 5, and 15 minutes.

if it's higher than the # of CPUs you have, that's often bad!

### memory
4 numbers: total/free/used/cached

One perhaps unexpected thing: total is NOT free+ used!

total = free + used + cached (filesystem cache)

### % CPU
confused stick figure with hair sticking out: 350%? what?

this column is given as the % of a single core. If you have 4 cores, this can go up to 400%!

### RES
this column is the "resident set size", aka how much RAM your process is using.

SHR is how much of the RES is shared with other processes

### htop
a prettier & more interactive version of top

Illustration of a graph showing different users of system resources with graphs showing used and cached memory in di
051
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 09/07/2026
tar permalink: wizardzines.com/comics/tar from our zine Bite Size Command Line!: wizardzines.com/zines/bite-size-com…
### panel 1
The tar file format combines many files into one file.  

a.txt  
b.txt 
dir/c.txt

tar files aren't compressed by themselves. Usually you gzip them: .tar.gz or .tgz!

### panel 2:
Usually when you use the 'tar' command, you'll run some incantation.  
To unpack a tar.gz, use:
```tar -xzf file.tar.gz``

person 1: what's xzf?  
person 2: let's learn!


### panel 3: -X is for extract 
into the current directory by default (change with -C)

### panel 4: -C is for create 
makes a new tar file!

### panel 5: -t is for list
lists the contents of a tar archive

### panel 6: -f is for file 
which tar file to create or unpack

### panel 7: tar can compress / decompress

-z gzip format (.gz)  
-j bzip2 format (.bz2)  
-J x2 format (.xz)  
& more! see the man page 

### panel 8: putting it together 
list contents of a .tar.bz2:  
```$tar tvf file.tar.bz2 ```  
j = verbose

create a .tar.gz:  
```$ tar -c2f file.tar.gz dir/```  
dir/ = files to go in the archive
020
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 07/07/2026
meet the remote permalink: wizardzines.com/comics/meet-the-rem… from our zine How Git Works: wizardzines.com/zines/git
### any repository you're pushing to / pulling from is called a "remote"

remotes can be:
- hosted by GitHub/GitLab/etc.
- on your own server
- just a folder on your computer 

### git push syntax

(same for git pull)

`git push origin main`

"`origin`" is the remote name, "`main`" is the remote branch.

the default name for a remote is origin but you can name it anything

### tip! 
I like to configure `push.autoSetupRemote true` to automatically set up tracking the first time I push a new branch


### remotes are where the drama happens

Smiling stick figure with short curly hair: I spent 3 hours working on `cats.py`

person: git pull

git, represented by a box with a smiley face: fun fact! your coworker totally rewrote that file!

### example: I use 2 remotes when contributing to open source projects

Diagram of a box labelled "local repo". Local repo has an arrow labelled "push to here", pointing to a box labelled "My personal GitHub fork". That box has an arrow labelled "pull reque
010
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 05/07/2026
meet the merge permalink: wizardzines.com/comics/meet-the-mer… from our zine How Git Works: wizardzines.com/zines/git
### merging is a huge thing in git

But the terminology around merging is a bit confusing:

- `git merge`
    isn't the only way to combine branches: you can also use `git rebase`!

- merge conflicts (surrounded by sad faces) can happen if you do any of these:
    - `git merge`
    - `git rebase`
    - `git cherry-pick`
    - `git revert`
    - `git stash pop `

- merge commits are only created by `git merge` 

Illustration of two stick figures talking, one is bald and looks unhappy, the other has curly hair and is smiling.

person 1: ... and what the heck is "fast forward"?

person 2: let's talk about it!

### there are 3 situations when combining branches

1. easy: no divergence ("fast-forward")   
Diagram of a box with a heart in it, labelled "main". Branching off it in a horizontal line, are three boxes with a star, a hash symbol, and a squiggle. The squiggle box is labelled "panda".

git merge moves the main branch forward to where the panda branch is, like this:
Same diagram as a
041
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 03/07/2026
meet the commit permalink: wizardzines.com/comics/meet-the-com… from our zine How Git Works: wizardzines.com/zines/git
### commits never change
once you've made a commit, it's set in stone:
- the files in it never change
- its diff never changes
- its history never changes
- the message/author never change

### commit hashes
commits never change because their ID is calculated from their contents.

Illustration of a box labelled `sha1 hash`. 

Going into the box are: 
- every file
- parent(s)
- message
- author 
- timestamp

Coming out of the box is an arrow labelled `3530a42`.

### you can think of commits as a pile of diffs

Illustration of a stack of boxes connected with lines. Each box is labelled "diff", except for the bottom one, which is labelled "START". The top box has an arrow pointing to it that says "current".

if you combine all the diffs together, you'll get the current state of the project!

(not how Git works, but a VERY useful way to think about commits!)

### you can also think of commits as a pile of snapshots

Illustration of a stack of boxes connected with lines. Each box is labelle
030
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 01/07/2026
meet the branch permalink: wizardzines.com/comics/meet-the-bra… from our zine How Git Works: wizardzines.com/zines/git
### theoretically you could use git without branches

You could keep track of your commit IDs manually:

Illustration of a smiling stick figure with medium-length straight hair.

person: hmm, what was I working on? oh yes, `a38b997`!

But most people use branches.

### every branch has 3 things

- a name (like `main`)
- a latest commit (like `2e9ffc`)
- a reflog of how that branch has evolved over time (page 26) 

Branches also sometimes have a corresponding remote branch which they "track"

### branches are core to how git stores your work

If your commits are "lost" (not on a branch) (page 13):
- (sad face) git's garbage collection will eventually delete them
- (sad face) they'll become incredibly difficult to find 

### the only difference between the main branch and any other branch is how you treat them

For example: it's common to never commit to main directly, and instead commit to other branches which you merge into main when you're done.

### all changes to a branch are record
011
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 29/06/2026
CSS variables permalink: wizardzines.com/comics/css-variables from our zine Hell Yes! CSS!: wizardzines.com/zines/css
### duplication is annoying

Illustration of a frowning stick figure with curly hair.

person, thinking: ugh, I have `color: #f79` set in 27 places and now I need to change it in 27 places

### define variables in any selector

```
body {
   --text-color: #f79;
body {
}

```
(applies to everything)
```
#header {
--text-color: #c50;
}
```
(applies to children of `#header`)

### use variables with `var()`
```
body {
   color: var(--text-color);
}
```
(variables always start with `--`)

### do math on them with `calc()`
```
#sidebar {
  width: calc(
    var (--my-var) + 1em
  );
}
```

### you can change a variable's value in Javascript
```
let root =
   document.documentElement; 
root.style.setProperty(
   '--text-color', 'black');
```


### changes to variables apply immediately
JS, represented by a box with a smiley face: set `--text-color` to red

css renderer, also represented by a box with a smiley face: ok everything using it is red now!
073
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 27/06/2026
CSS units permalink: wizardzines.com/comics/units from our zine Hell Yes! CSS!: wizardzines.com/zines/css
### CSS has 2 kinds of units: absolute & relative
absolute: 
- px
- pt
- pc
- in
- cm
- mm

relative
- em
- rem
- vw
- vh
- %

### `rem`
the root element's font size

`1rem` is the same everywhere in the document. `rem` is a good unit for setting font sizes!

### `em`
the parent element's font size
```
.child {
   font-size: 1.5em;
}
```

Illustration of a box labelled "parent". Inside it is a box labelled, in larger text, "child". An arrow is pointing to the "child" text, labelled "font size is 1.5 x parent".


### O is the same in all units
```
.btn {
   margin: 0;
}
```
also, `0` is different from `none`. `border: 0` sets the border width and `border: none` sets the style

### 1 inch = 96 px
on a screen, 1 CSS "inch" isn't really an inch, and 1 CSS "pixel" isn't really a screen pixel. look up "device pixel ratio" for more.

### rem & em help with accessibility
```
.modal {
   width: 20rem;
}
```
this scales nicely if the user increases their browser's default font size
093
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 25/06/2026
CSS transitions permalink: wizardzines.com/comics/css-transiti… from our zine Hell Yes! CSS!: wizardzines.com/zines/css
### an element's computed style can change

2 ways this can happen:

1. pseudo-classes   
(like `:hover`)

2. Javascript code   
`el.classList.add('x')`

### new styles change the element instantly...
```
a:hover {
   color: red;
}
```
the element will turn red right away

### unless you set the transition property

```
a {
   color: blue;
   transition: all 2s;
}
a:hover {
   color: red;
}
```
("`all 2s`" = will fade from blue to red over 2s)


### transition has 3 parts
`transition: color 1s ease;`

`color`: which CSS properties to animate   
`1s`: duration   
`ease`: timing function

### not all property changes can be animated....
`list-style-type: square;`

CSS renderer, represented by a box with a smiley face: I don't know how to animate that, sorry!

### ...but there are dozens of properties that can
if it's a number or color, it can probably be animated! 
```
font-size: 14px;
rotate: 90deg; 
width: 20em;
```
062
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 23/06/2026
CSS testing checklist permalink: wizardzines.com/comics/testing-chec… from our zine Hell Yes! CSS!: wizardzines.com/zines/css
Finally, it's important to test your site with different browsers, screen sizes, and accessibility evaluation tools.

### browsers
- Chrome
- Safari
- Firefox
- maybe others!

### sizes
- small phone (300px wide)
- tablet (~700px)
- desktop (~1200px)

### accessibility
- colour contrast
- text size
- keyboard navigation
- works with a screen reader

### performance
- fake a slow/high latency network connection!

Illustration of a smiling stick figure with curly hair.

person: the most important thing is to know your users! Check your analytics: if 10% of your users are using IE, test your site on IE!
020
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 21/06/2026
tshark permalink: wizardzines.com/comics/tshark from our zine Bite Size Networking!: wizardzines.com/zines/bite-size-net…
### Wireshark is an amazing graphical packet analysis tool
("Wireshark" has hearts around it) 

tshark is the command line version of Wireshark

it can do 100x more things than tcpdump (heart)

### `-Y`
filter which packets are captured

```
tshark -y
'http.request.method
== "GET"
```
(uses Wireshark's SUPER POWERFUL filter language)

### `-d`
is for "decode as"

tells tshark what protocol to interpret a port as

Example: 8888 is often HTTP!

```
$tshark
-d tcp.port==8888,http
```

### `-T FORMAT`
Output format. My favourites:
- json
- fields: csv/tsv 
(for these above two you can specify which fields you want with `-e`)
- text: default summary

### `-e`
Which fields to output. Ex:
```
$tshark -T fields
-e http.request.method
-e http.request.uri
-e ip.dst
```
(supports WAY more protocols than HTTP)
```
GET    /foo   92.183.216.34
POST   /bar   10.23.38.132
```

### `-r file.pcap`
analyze packets from a file instead of the network

### `-w`
(same as tcpdump)

Write captured packets to a
062
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 19/06/2026
tcpdump permalink: wizardzines.com/comics/tcpdump from our zine Bite Size Networking!: wizardzines.com/zines/bite-size-net…
### tcpdump lets you view network packets being sent and received

happy little stick figure: it's not the easiest to use but it's usually installed (heart)

### `-n`
don't try to resolve IP addresses/ports to DNS/port names. makes it run faster

### `i wlan0`
Which network interface to capture packets on

person: I often use "`-i any`" to make sure I'm not missing any packets!

### `-w file.pcap`
Write packets to a file for later analysis with tcpdump/tshark/wireshark/another tool

pcap is short for "packet capture"

### `-A`
print packet contents, not just headers. Nice if you want to quickly see what a few packets contain.

### `-c 1000000`
Only capture a limited count of packets.

person: I use it with `-w` so I don't accidentally fill up my disk!
010
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 17/06/2026
tc permalink: wizardzines.com/comics/tc from our zine Bite Size Networking!: wizardzines.com/zines/bite-size-net…
### tc
is for "traffic control"

humanoid traffic light, its hand held up as though directing traffic: packets! stop/slow down/go the other way!

great for simulating network problems!

### make your internet slow
```
$ sudo tc qdisc add dev
  wlp3s0 root netem
  delay 500ms
```
(delay packets by 500ms)

and fast again:
```
$ sudo tc qdisc del dev
  wlp3s0 root netem
```

### netem rules
netem ("network emulator") is a part of tc that lets you:
- drop
- duplicate
- delay
- corrupt

packets. see the man page `$ man netem`

### make your brother's internet slow
Have a Linux router? You can configure tc on it to make your brother's internet slower than yours. google "tc QoS" for a start.

### show current tc settings
```
$ tc qdisc show
$ tc class show dev DEV
$ tc filter show dev DEV
```

### panel 6

smiling stick figure: `tc` can do 10 million more things! This is just the beginning!
081
Julia's Reruns Bot @b0rk-reruns.jvns.ca · 15/06/2026
writing tip: say something surprising permalink: wizardzines.com/comics/surprise
061