Skip to content
Linux Basics: Prevent Accidental Output Overwrites with noclobber

Linux Basics: Prevent Accidental Output Overwrites with noclobber

October 22, 2026

A plain > can replace an existing report before the command produces any useful output. Bash’s noclobber option makes that redirection fail for an existing regular file. Practice checking the refusal, making a deliberate exception, and limiting the option to one part of a script.

These examples were tested on Linux with GNU Bash 5.2.37. Use Bash rather than sh. Each script creates a different named text file in the fresh scratch directory. Run each once before cleanup. Its first protected write refuses an existing practice file rather than reusing it.

Prepare a scratch directory

You need Bash, a text editor, and the cat, mktemp, rm, and rmdir utilities. Keep using the same terminal. Save each named source file in this directory before running it. The guards stop setup if it fails; invoking bash explicitly avoids changing executable permissions. No administrator access is needed.

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

1. Refuse an accidental replacement

Save this as clobber-protect.sh:

#!/usr/bin/env bash
set -o noclobber
printf 'original report\n' > clobber-protected.txt || exit 1
if { printf 'replacement\n' > clobber-protected.txt; } 2>/dev/null; then
  printf 'Unexpected overwrite\n'
  exit 1
else
  printf 'Existing file kept\n'
fi
IFS= read -r saved < clobber-protected.txt || exit 1
printf 'Content: %s\n' "$saved"

Run it:

bash clobber-protect.sh

Output:

Existing file kept
Content: original report

The first write creates a new file. The second redirection fails before its printf runs, and the conditional handles that failure. Reading the file afterward confirms that the original line remains.

The enclosing brace group redirects Bash’s expected error message to /dev/null so the example can print a stable explanation. Keep diagnostics visible in normal troubleshooting. If a write fails unexpectedly, distinguish overwrite protection from permission errors, a missing parent directory, or a full filesystem rather than assuming every failure has the same cause.

2. Replace once deliberately, then append

Save this as clobber-override.sh:

#!/usr/bin/env bash
set -C
printf 'draft\n' > clobber-override.txt || exit 1
printf 'reviewed\n' >| clobber-override.txt || exit 1
printf 'approved\n' >> clobber-override.txt || exit 1
printf 'After replacement and append:\n'
cat -- clobber-override.txt

Run it:

bash clobber-override.sh

Output:

After replacement and append:
reviewed
approved

set -C is the short form of enabling noclobber. The >| operator makes one explicit overwrite exception, so draft is replaced by reviewed. Appending with >> still works while the option is enabled, adding approved without discarding the preceding line.

Use the exception only after choosing the destination deliberately. It does not bypass filesystem permissions, guarantee that the producing command succeeds, or make the replacement transactional. A failed producer may still leave an empty or partial file after an allowed redirection.

3. Limit protection to a subshell

Save this as clobber-scope.sh:

#!/usr/bin/env bash
set +C
(
  set -C
  printf 'inside\n' > clobber-scope.txt || exit 1
  if { printf 'refused\n' > clobber-scope.txt; } 2>/dev/null; then
    exit 1
  else
    printf 'Subshell: overwrite blocked\n'
  fi
) || exit 1
printf 'outside\n' > clobber-scope.txt || exit 1
printf 'After returning to the outer shell: '
cat -- clobber-scope.txt

Run it:

bash clobber-scope.sh

Output:

Subshell: overwrite blocked
After returning to the outer shell: outside

The outer script explicitly starts with protection disabled. The parenthesized section enables it locally and confirms that a repeated write is blocked. When that section finishes, the outer shell can overwrite the file using plain > because its own option was never changed.

A script can use this pattern around a small export operation without changing later writes. The standalone script does not change the launching terminal’s settings either. Do not assume an option enabled in one shell is active in every other process that may write the same file.

Keep in mind

This option guards particular shell output redirections, not all filesystem changes. It does not stop an editor, cp, or a program that opens files itself. It is not a backup, a general file lock, or a complete defense against hostile pathname changes. Keep important outputs backed up and choose a proper atomic-write strategy when partial results would be harmful.

Clean up

In the same terminal, remove only the named practice files, return to your original directory, and remove the empty scratch directory:

rm -- clobber-protected.txt clobber-override.txt clobber-scope.txt
rm -- clobber-protect.sh clobber-override.sh clobber-scope.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

References

Acknowledgements

This post was created with assistance from AI.

Last updated on