Mastering File Creation in Linux: Practical Commands Beyond touch
Creating files in Linux is fundamental—yet engineering workflows often demand more than a zero-byte placeholder or simple timestamp update. File initialization, permission controls, and directory structuring all play a role in robust system operations. Here's a reality-checked look at what seasoned engineers actually use when managing files from the CLI.
Default: touch
—But the Real World Needs More
touch app.log
Classic, fast, but basic: creates an empty file (or updates mtime if app.log
exists). If you need a file for logging in a systemd service on RHEL 8, this works fine. However, touch
does not:
- Add content
- Set custom permissions during create
- Build out missing parent directories
- Scaffold config or template files
For automation, provisioning, or repeatable workflows, these limits matter.
Populating Files: echo
and cat
with Here-Docs
Quick config generation is a recurring use case.
cat > /etc/grafana/grafana.ini <<EOF
[server]
protocol = https
http_port = 3000
EOF
No editor, no fuss. Hands-on for entrypoint scripts or CI jobs. Contrast with:
echo "[ok]" > healthcheck.status
Note: echo
replaces file content, and trailing newlines can be inconsistent—useful for simple flags, less so for structured configs.
Gotcha
Appending with >>
avoids destructive overwrites. Overlook this in a build script and you risk clobbering your last run’s logs.
Precision Formatting: printf
For controlled output (especially in scripting), printf
is indispensable:
printf "user=%s\nuid=%d\ngid=%d\n" "svc-acc" 1005 1005 > /etc/test-user.conf
printf
respects escape sequences, tab alignment, and octal/hex values—options echo
simply ignores or mangles across distributions (compare bash
vs. dash
behavior).
Creating Empty Files Without touch
> bootstrap.done
Redirection yields a zero-byte file or truncates the existing one. Sometimes, that's all a healthcheck probe or sentinel needs. No extra processes spawned—faster on constrained systems (e.g., containers without coreutils
installed).
Controlled Permissions On Creation: install
A common mistake: touch
then chmod
. Prefer atomic creation when possible:
install -m 640 /dev/null /var/secrets/.env
Creates the file with restricted permissions in one go. This matters for secrets or when files must never be group-writable. Note: /dev/null
as the source ensures the file is empty, but you can source a template instead.
Scaffold Directories and Files
Frequently, provisioning scripts fail when a parent path is missing (e.g., on first deploy):
mkdir -p /data/app/logs && touch /data/app/logs/init.log
Or for permissions:
mkdir -p /opt/scripts/monitor && install -m 700 /dev/null /opt/scripts/monitor/runner.sh
There’s no single Linux command that natively creates all parent directories and the file in one—pair mkdir -p
and your file creation method.
Non-Regular Files: Named Pipes and Device Nodes
For pipelines or system-level interfaces:
mkfifo /tmp/exchange.fifo
Required for legacy daemons expecting named pipes. Device special files (rare in userland, but critical for embedded/system contexts):
sudo mknod /dev/net/tun c 10 200
Parameters c
(char device) and the major/minor numbers must match kernel expectations. Wrong here, and the kernel logs device not found errors.
Quick Reference
Command/Pattern | Purpose | Example | Notes |
---|---|---|---|
touch | Empty file or update mtime | touch foo.log | Standard, but lacks templating/permissions |
echo > file | Simple content, overwrite existing | echo "ready" > /tmp/status | Trailing newline may be OS-dependent |
cat <<EOF > file | Multi-line, interactive/scripted content | cat <<EOF > /var/app/env | Use for configs, credentials |
printf | Structured, formatted file creation | printf "A\tB\n" > table.tsv | More portable than echo -e |
> file | Create or empty file without spawning process | > /run/ok | Fastest method for empty file |
install -m | New file with custom permissions | install -m 600 /dev/null secret.txt | Atomic for security contexts |
mkdir -p && ... | Build missing dirs then create/seed file | mkdir -p /tmp/a/b && touch /tmp/a/b/c | No one-step native alternative |
mkfifo | Named (FIFO) pipe | mkfifo /tmp/myfifo | Used for inter-process comms |
mknod | Special file (block/char) | mknod /dev/x c 1 3 | Root required, check kernel docs |
Practical Note
Some distributions package a minimalist shell (e.g., BusyBox in Alpine), lacking certain utilities. In containers, touch
and install
may not be present; redirect (> file
) and printf
remain universally available if sh
is present.
Non-obvious tip
Combining file creation with ACLs in one pass isn't possible natively; follow up with setfacl
:
install -m 640 /dev/null log.secure
setfacl -m u:monitor:r log.secure
Summary
Seasoned Linux engineers use a blend of touch
, file redirection, printf
, and install
for file creation depending on context—automation scripts, permissions, directory scaffolding, and content templating. There is no universal “best”; choose based on workflow, security requirements, and toolchain limitations.
No one-liner fits all. Know the alternatives—scripts break less and servers stay compliant.