# mkcd: The missing shell shortcut It seems like you often `cd` to a new directory. How often? I have analyzed my [fish shell](https://fishshell.com) history on a Linux machine where it spans from 2019 to 2025 and has just over 100K entries. If you have seen a fish history file, it looks like a subset of YAML: ```plaintext - cmd: add-apt-repository ppa:zfs-native/stable when: 1342217584 - cmd: nvim dir.sha256 when: 1614189938 paths: - dir.sha256 ``` However, it is [not valid YAML](https://github.com/fish-shell/fish-shell/issues/4675#issuecomment-359205359). With this in mind, I wrote a script to analyze history line-by-line using Python's helpful [`fileinput`](https://docs.python.org/3/library/fileinput.html) module. [Download](mkcd/analyze.py). ```python #! /usr/bin/env python3 import fileinput mkdir = 0 cd_after_mkdir = 0 after_mkdir = None for line in fileinput.input(errors="surrogateescape"): args = line.split() # Ignore quoting. if args[:2] != ["-", "cmd:"]: continue match args[2:]: case ["mkdir", path, *_] | ["sudo", "mkdir", path, *_]: path = path.rstrip("/") mkdir += 1 after_mkdir = path continue case ["cd", path, *_]: path = path.rstrip("/") if path == after_mkdir: cd_after_mkdir += 1 case _: pass after_mkdir = None print(f"{mkdir = }\n{cd_after_mkdir = }") ``` You can try this script on your history. Here is what I get on my machine: ```plaintext > ./analyze.py ~/.local/share/fish/fish_history mkdir = 1244 cd_after_mkdir = 213 ``` 213 ÷ 1244 × 100% ≈ 17% of `mkdir` commands are immediately followed by changing to the new directory. This is for my user account; for root, I have `mkdir = 30` and `cd_after_mkdir = 3`, respectively. The numbers are approximate. The script ignores argument quoting, and my shell history covers time after I replaced `mkdir` followed by `cd`. Still, this seems like a lot. Why is there no standard shortcut to perform `mkdir` followed by `cd`? It doesn't seem any prominent shell includes one. By contrast, `ll` for `ls -l` and `la` for `ls -la` are standard in fish. I know I didn't invent `mkcd` and only adopted it years after reading the first Internet comment that described it. This leads me to suspect the friction isn't obvious. You realize the standard workflow is tiresome _after_ you start using `mkcd`. (This means you adopt `mkcd` at your peril.) Where does `mkcd` come from? [Multiple discovery](!W) is likely because the core idea is so simple. I have [searched Hacker News](https://hn.algolia.com/?dateEnd=1752323076&dateRange=custom&dateStart=1104537600&page=1&prefix=false&query=mkcd&sort=byDate&type=comment) with the official Algolia search and Reddit and [textfiles.com](https://textfiles.com) using DuckDuckGo and Google. The earliest instances I found were a [January 2008 comment](https://news.ycombinator.com/item?id=104208) by HN user dreish and an April 2010 post ["mkcd"](https://onethingwell.org/post/561049890/mkcd) by Jack Mottram on the Tumblr blog _One Thing Well_. The dreish comment uses `mkdir -p`, but Jack Mottram only replaced `mkdir` with `mkdir -p` in May 2010 follow-up ["mkcd improved"](https://onethingwell.org/post/586977440/mkcd-improved) after a message from a reader, suggesting he didn't borrow from the HN comment. [Searching Usenet Archives](https://www.usenetarchives.com/index.php?s=mkcd&t=0&p=1) finds a [linux.debian.user.german post from 2003](https://www.usenetarchives.com/view.php?id=linux.debian.user.german&mid=PEdWVVkuMTdDLjIxQGdhdGVkLWF0LmJvZmguaXQ%2B) by Robert Michel asking how to implement `mkcd` as a Bash alias. Other discussions that match "mkcd" on Usenet Archives are about burning optical media. After seeing the recommendation for `mkcd` enough times, in 2024 I decided to try it. I implemented it for fish and quickly became a fan. Over a year later, I can definitely recommend it. To try it yourself, you can install `mkcd.fish` to your fish functions directory (likely `~/.config/fish/functions/`). [Download](mkcd/mkcd.fish). ```fish # From https://dbohdan.com/mkcd # License: MIT # https://dbohdan.com/mit-license/2025 function mkcd --argument name --description "Create a directory and 'cd' to it" if test (count $argv) -ne 1 printf 'usage: mkcd name\n' >&2 return 2 end mkdir -p $name cd $name end ``` ## See also - [My setup](/setup) - [Small utilities](/small-utils) ## Page metadata URL: Published 2025-07-13, updated 2025-07-18. Tags: - command line - fish shell - personal computing - shell - tools