How to Create and Delete Files in Bash

How to Create and Delete Files in Bash

Every script I’ve ever written eventually needs to touch a file — whether that’s writing a log entry, generating a config, or clearing out something temporary. Files are the most basic unit of data storage in Linux, and Bash gives you several simple but powerful ways to create and remove them. In this article, I’ll cover everything from the simplest one-liners to more advanced patterns I use in real automation scripts.

Why File Management Matters

If you’re writing shell scripts, you’re going to be creating temporary files, writing output, or cleaning up after a process finishes. Understanding the tools available — touch, redirection operators, rm, and a few supporting commands — means you can build reliable scripts that don’t leave a mess behind or fail unexpectedly.

Creating Files in Bash

Using touch

The classic way to create an empty file is touch:

touch myfile.txt

If myfile.txt doesn’t exist, this creates it as an empty file. If it already exists, touch doesn’t erase the content — instead, it just updates the file’s last-modified timestamp. This distinction trips people up sometimes, since they expect touch to reset the file.

Creating Multiple Files at Once

touch file1.txt file2.txt file3.txt

You can also combine this with brace expansion:

touch file{1..5}.txt

This creates file1.txt through file5.txt in one command.

Creating a File with Content Using Redirection

If you want to create a file and put something in it immediately, use the > redirection operator:

echo "Hello, world!" > greeting.txt

This creates greeting.txt (or overwrites it if it already exists) with the text “Hello, world!” inside.

To append to a file instead of overwriting it, use >>:

echo "Another line" >> greeting.txt

Creating a File with cat and a Heredoc

For multi-line content, a heredoc is often cleaner than several echo commands:

cat > notes.txt << 'EOF'
This is line one.
This is line two.
This is the final line.
EOF

Everything between << 'EOF' and the closing EOF gets written into notes.txt. Quoting 'EOF' prevents variable expansion inside the block, which is useful when you want the literal text preserved.

Creating an Empty File with >

You can also create an empty file directly with redirection:

> emptyfile.txt

This is functionally similar to touch for a file that doesn’t exist yet, though it will truncate an existing file to zero bytes — a subtle but important difference from touch.

Checking If a File Exists Before Creating It

if [ ! -f "myfile.txt" ]; then
    touch myfile.txt
    echo "File created."
else
    echo "File already exists."
fi

The -f test checks whether the given path exists and is a regular file.

Deleting Files with rm

The standard command for deleting files is rm:

rm myfile.txt

This permanently deletes myfile.txt. There’s no recycle bin in the terminal by default — once it’s gone, it’s gone (barring specialized recovery tools, which aren’t guaranteed to work).

Deleting Multiple Files

rm file1.txt file2.txt file3.txt

Deleting Files with a Pattern

rm *.log

This deletes every file in the current directory ending in .log. Wildcards are powerful, but they’re also where a lot of accidental deletions happen — always double-check the pattern before running it.

Forcing Deletion Without Prompts

rm -f myfile.txt

The -f flag suppresses errors if the file doesn’t exist and skips any confirmation prompts. It’s commonly combined with scripts that clean up files that may or may not be present.

Asking for Confirmation Before Deleting

rm -i myfile.txt

This prompts you with remove myfile.txt? before deleting, which is a good habit when working with files you’re not 100% sure about.

How These Commands Work Internally

touch works by calling the utimensat() system call to update a file’s access and modification timestamps. If the file doesn’t exist, it first calls open() with the O_CREAT flag to create an empty file, then updates the timestamps.

rm calls the unlink() system call, which removes the directory entry pointing to the file’s inode. The actual data isn’t necessarily erased right away — the space is simply marked as free, which is part of why deleted files can sometimes be recovered with forensic tools shortly after deletion, though this isn’t something to rely on.

Redirection operators (> and >>) are handled directly by the shell before the command even runs. The shell opens the target file (truncating it for >, or opening it in append mode for >>) and connects the command’s standard output to that file descriptor.

Real-World Use Cases

Logging script output:

#!/bin/bash
LOG_FILE="/var/log/myscript.log"
echo "$(date): Script started" >> "$LOG_FILE"
# ... script logic here ...
echo "$(date): Script finished" >> "$LOG_FILE"

Generating a configuration file dynamically:

#!/bin/bash
cat > app.conf << EOF
hostname=$(hostname)
generated_on=$(date)
mode=production
EOF

Notice that this heredoc uses EOF without quotes, so variables like $(hostname) and $(date) get expanded into the file.

Cleaning up temporary files after a script runs:

#!/bin/bash
TEMP_FILE=$(mktemp)
echo "Working with temp file: $TEMP_FILE"
# ... use the file ...
rm -f "$TEMP_FILE"

Using mktemp to generate a unique temporary filename avoids collisions with other running processes.

Automation Example: Rotating Log Files

#!/bin/bash

LOG_DIR="/var/log/myapp"
MAX_AGE_DAYS=30

# Create today's log file if it doesn't exist
TODAY_LOG="$LOG_DIR/app-$(date +%Y-%m-%d).log"
touch "$TODAY_LOG"

# Delete log files older than MAX_AGE_DAYS
find "$LOG_DIR" -type f -name "*.log" -mtime +$MAX_AGE_DAYS -exec rm -f {} \;

echo "Log rotation complete."

This script creates a fresh log file for the current day and removes anything older than 30 days using find combined with rm -f.

Best Practices

  • Use touch when you just need an empty file or want to update a timestamp; use > when you intend to reset content.
  • Quote file paths and variables ("$file") to handle spaces and special characters safely.
  • Prefer mktemp over manually naming temporary files, to avoid collisions and race conditions.
  • Check for a file’s existence with -f before operating on it in scripts that shouldn’t assume the file is there.
  • When deleting based on a pattern, run ls with the same pattern first to preview what will be affected.

Security Considerations

  • Never run rm -f with unvalidated user input in a script — if a variable is empty or contains unexpected characters, you could delete far more than intended.
  • Set restrictive permissions on sensitive files right after creating them, using chmod 600 filename for files that should only be readable by the owner.
  • Avoid storing secrets (passwords, API keys) directly in plaintext files that scripts create, unless the file’s permissions and location are properly secured.
  • When creating files in shared or world-writable directories like /tmp, use mktemp rather than a predictable filename, to avoid symlink attacks where another user pre-creates a file at the path you expect to use.

Optimization Tips

  • For bulk file creation, brace expansion (touch file{1..1000}.txt) is far faster than looping with a for statement, since it avoids repeated process calls.
  • When deleting large numbers of files matching a pattern, find /path -name "*.tmp" -delete is generally faster and more memory-efficient than rm *.tmp in directories with a huge number of files, since rm with a glob can hit the command-line argument length limit.

Troubleshooting

“No such file or directory” when deleting: The file may have already been removed, or the path might be wrong. Use ls -la to confirm the exact name and location.

“Permission denied” when creating or deleting a file: Check the directory’s permissions with ls -ld . — you need write permission on the containing directory, not just the file itself, to create or delete files inside it.

Heredoc content not expanding variables as expected: If you quoted the delimiter (<< 'EOF'), variables won’t expand. Remove the quotes (<< EOF) if you want expansion.

Common Mistakes

  1. Assuming touch clears the contents of an existing file — it doesn’t.
  2. Using rm with a wildcard without previewing the affected files first.
  3. Forgetting that > truncates existing files, which can silently wipe out data you meant to keep.
  4. Not quoting variables in rm commands, which can cause word-splitting issues with filenames that contain spaces.

FAQs

How do I create a file with specific permissions? Create it first with touch or redirection, then set permissions with chmod, e.g. chmod 644 file.txt.

What’s the difference between touch and > for creating files? touch creates an empty file if it doesn’t exist and preserves existing content if it does. > creates the file if needed but also truncates any existing content to zero bytes.

Can I recover a file after running rm? Not reliably through Bash itself. Recovery depends on the file system and whether the space has been overwritten. Backups are the only dependable safety net.

How do I delete a file only if it’s older than a certain date? Use find, like find . -name "file.txt" -mtime +7 -delete, which deletes matching files older than 7 days.

Summary

Creating and deleting files in Bash is built around a small set of dependable tools: touch for creating empty files or updating timestamps, redirection operators for writing content, and rm for deletion. The details matter — knowing that touch won’t clear existing content, that > truncates, and that rm offers no undo will save you from some painful mistakes. With a bit of care around quoting and validating input, these commands become second nature for everyday scripting.

References

  • GNU Coreutils Manual: https://www.gnu.org/software/coreutils/manual/coreutils.html
  • Bash Reference Manual (Redirections): https://www.gnu.org/software/bash/manual/bash.html#Redirections
  • touch(1) man page: https://man7.org/linux/man-pages/man1/touch.1.html
  • rm(1) man page: https://man7.org/linux/man-pages/man1/rm.1.html
Total
2
Shares

Leave a Reply

Previous Post
How to Check File Existence in Bash

How to Check File Existence in Bash

Next Post
How to Create and Delete Directories in Bash

How to Create and Delete Directories in Bash

Related Posts