Terminal

How to Create a File in Terminal on Mac (touch, echo, cat)

Published Nov 8, 2026
Tested on a real Mac. Ran touch, echo/printf with > and >>, cat heredocs, noclobber, mkfile, dd, truncate, touch -t and bare > redirection in zsh and bash in a scratch folder on an M3 Mac (macOS 26.6.2, zsh 5.9); open -e (TextEdit) and nano were not executed because they open interactive editors. Test machine: MacBook Air (M3, 16 GB), macOS Tahoe 26.6.2, zsh 5.9.
On this page
  1. Create an empty file with touch
  2. Create a file with text: echo, printf and >
  3. Create a multi-line file with cat (heredoc)
  4. The zsh ”> file” trap (it waits for input)
  5. Create a large test file (mkfile, dd, truncate)
  6. Common errors
  7. Common questions

To create a new, empty file in Terminal on a Mac, use touch followed by the file name:

touch notes.txt

That’s it. The file appears in the folder you are in, with zero bytes. To create a file that already has text in it, use echo with > instead: echo "hello" > hello.txt.

Below are all the ways I tested on a MacBook Air M3 (macOS Tahoe 26.6.2, zsh 5.9), plus a zsh quirk that makes one popular shortcut hang, and a permissions surprise with mkfile.

Create an empty file with touch

touch ships with macOS at /usr/bin/touch. Nothing to install.

touch notes.txt
ls -l notes.txt
file notes.txt
-rw-r--r--@ 1 you  staff  0 Nov  8 11:05 notes.txt
notes.txt: empty

The 0 is the size in bytes. The @ at the end of the permissions means the file has an extended attribute. On macOS Tahoe, files created from Terminal get com.apple.provenance, which you can see with xattr notes.txt. It is harmless and does not change the file’s contents.

You can create several files in one go:

touch a.txt b.txt c.md

Need the file somewhere else? Give a path. If you are not sure which folder you are in, open . shows it in Finder (see how to open a folder in Finder from Terminal).

Watch out for spaces in names

Spaces split arguments. This was my test:

touch "my notes.txt"
touch my notes2.txt
ls -1
my
my notes.txt
notes2.txt

The quoted version made one file called my notes.txt. The unquoted version quietly made two files: my and notes2.txt. No error, no warning. Always quote names with spaces.

touch does not overwrite existing files

If the file already exists, touch leaves the contents alone and only updates the “last modified” time:

-rw-r--r--@ 1 you  staff  5 Nov  8 11:05:16 2026 hello.txt
-rw-r--r--@ 1 you  staff  5 Nov  8 11:05:29 2026 hello.txt

Same 5 bytes, new timestamp. That makes touch the safe choice when you just want the file to exist. You can also set a specific date with -t (format YYYYMMDDhhmm):

touch -t 202501011200 old.txt
-rw-r--r--@ 1 you  staff  0 Jan  1 12:00:00 2025 old.txt

Create a file with text: echo, printf and >

The > symbol sends a command’s output into a file, creating it if needed:

echo "hello" > hello.txt
echo "second line" >> hello.txt
cat hello.txt
hello
second line

>> appends to the end. A single > replaces everything. When I ran echo "oops" > hello.txt afterwards, cat printed only oops. There is no undo.

If you want zsh to stop you from overwriting by accident, turn on noclobber for the session:

setopt noclobber
echo x > hello.txt
zsh:1: file exists: hello.txt

With noclobber on, use >| when you really do mean to overwrite.

zsh echo and bash echo are different

On a Mac, the default shell is zsh, and zsh’s echo turns \n into a real line break. Bash’s does not. Same command, different files:

zsh -c 'echo "a\nb" > z.txt'; cat z.txt
bash -c 'echo "a\nb" > b.txt'; cat b.txt
a
b
a\nb

If you copy scripts from Linux tutorials, use printf instead. It behaves the same everywhere:

printf 'line one\nline two\n' > p.txt

Create a multi-line file with cat (heredoc)

For config files or scripts, a “heredoc” lets you type many lines at once:

cat > config.txt <<EOF
user=$USER
home=$HOME
EOF

The gotcha: variables get expanded. My file contained my real username and home path, not the text $USER:

user=you
home=/Users/you

Quote the marker to keep the text exactly as typed:

cat > config.txt <<'EOF'
user=$USER
home=$HOME
EOF
user=$USER
home=$HOME

That single pair of quotes around EOF matters a lot when you write shell scripts or .env files.

The zsh ”> file” trap (it waits for input)

Many guides say you can create an empty file with just:

> file.txt

In bash, that’s true. It makes an empty file instantly. In zsh, the Mac default, a redirect with no command runs cat behind the scenes (zsh calls it NULLCMD, and echo $NULLCMD prints cat). So Terminal sits there waiting for you to type. Whatever you type ends up in the file.

I proved it by piping text in:

echo "typed text" | zsh -c '> redir2.txt'
cat redir2.txt
typed text

If your Terminal seems frozen after > file.txt, press Control-D to finish (or Control-C to cancel). To get the bash behavior in zsh, put a colon first, which is a “do nothing” command:

: > file.txt

That created a 0-byte file instantly in my test. It also empties an existing file, so be careful.

Create a large test file (mkfile, dd, truncate)

Sometimes you need a file of a specific size to test uploads or disk space. macOS has three built-in tools:

mkfile -n 1m big.bin
dd if=/dev/zero of=dd.bin bs=1m count=2
truncate -s 5M t.bin

They don’t behave the same, and two things surprised me:

-rw-------@ 1 you  staff   1.0M Nov  8 11:05 big.bin
-rw-r--r--@ 1 you  staff   2.0M Nov  8 11:05 dd.bin
-rw-r--r--@ 1 you  staff   5.0M Nov  8 11:05 t.bin
ToolPathPermissionsReal disk use
mkfile -n 1m/usr/sbin/mkfile-rw------- (only you)1.0M
dd ... count=2/bin/dd-rw-r--r--2.0M
truncate -s 5M/usr/bin/truncate-rw-r--r--0B

First, mkfile makes files readable only by you, unlike touch, dd and truncate. That can trip up a web server or another user account that needs to read the file.

Second, truncate makes a “sparse” file. ls says 5.0M, but du -h t.bin printed 0B. The space is not actually used on disk. Great for quick tests, but useless if you are trying to fill up a disk on purpose. Use dd or mkfile for that.

Common errors

“No such file or directory”: the folder doesn’t exist yet. touch won’t create folders:

touch: nofolder/x.txt: No such file or directory

Create the folders first with mkdir -p:

mkdir -p projects/demo/src && touch projects/demo/src/app.py

“Read-only file system” or “Operation not permitted”: you tried to write into a protected macOS location. I got Read-only file system for / and Operation not permitted for /usr. Those are part of the sealed system volume, and you should not put your own files there. Work in your home folder instead.

Common questions

How do I create a file and open it right away?

Create it, then open it in an editor. open -e notes.txt opens the file in TextEdit. nano notes.txt edits it right inside Terminal and also creates the file if it doesn’t exist. I did not run these two here because they open interactive editors.

How do I create a hidden file like .env?

Start the name with a dot: touch .env. A plain ls hides it. Use ls -a to see it. In Finder, press Command-Shift-period, or follow the guide on how to show hidden files on Mac.

Does the file extension matter?

Not to Terminal. touch report and touch report.txt both make an empty file. The extension only tells Finder which app to open it with.

What’s the difference between touch and > for creating files?

touch never changes the contents of an existing file. > empties it first. If you only want to make sure a file exists, use touch.

How do I create a folder instead of a file?

Use mkdir foldername. Add -p to create nested folders in one go, like mkdir -p a/b/c.