Course contentsShow
← Linux
Lesson 119 of 1,8192. Deep Dive into Bash ScriptingFree lesson

Atomic File Operations

Use temporary file atomicity and file descriptors to prevent race conditions.

In this lesson, you will learn how to use temporary files and file descriptors to ensure your data writes remain "all or nothing," even if your script is interrupted.

The Problem: Partial Writes

When you write to a file directly (e.g., echo "data" > config.txt), the operation isn't necessarily atomic. If your script crashes or the system loses power exactly while the shell is clearing the file to write the new data, you end up with a corrupted, empty, or half-written file. In a high-concurrency environment where multiple processes might be reading that file, this race condition leads to unpredictable behavior.

The Solution: The "Write-Rename" Pattern

To guarantee atomicity, we perform the write in a safe "sandbox" and then swap the files. Linux treats the mv (rename) command as an atomic operation—at the file system level, the pointer to the file is updated instantly.

Here is how you implement this pattern in a Bash script:

# 1. Create a temporary file in the same directory (so they are on the same filesystem)
tmp_file=$(mktemp config.txt.XXXXXX)

# 2. Write your data to the temporary file
echo "New configuration data" > "$tmp_file"

# 3. Use 'mv' to atomically overwrite the destination
mv "$tmp_file" config.txt

Leveraging File Descriptors

If you need to keep a file open for a long period while performing multiple operations, you can use file descriptors to maintain a lock on a temporary workspace. By using a file descriptor (exec 3> "$tmp_file"), you ensure that your script maintains a direct handle to the temporary file, preventing other processes from interfering with the data stream before you commit the final rename.

By always writing to a unique temporary file first and then renaming it to the target filename, you ensure that any process reading config.txt either sees the old version or the fully completed new version—never a mangled mix of the two.

Key Takeaway: Never write directly to a production file; write to a temporary file on the same filesystem and use an atomic mv to finalize the update.