Question Details

No question body available.

Tags

bash

Answers (3)

March 31, 2026 Score: 6 Rep: 300,198 Quality: Medium Completeness: 50%

Use the noclobber flag, enabled with set -C (or by running your script with bash -C):

set -C outputthedata > "$filepath" || exit

If filepath already exists, the shell will write an error like yourscript: line 2: filepath: cannot overwrite existing file and exit before outputthedata is started.


If you want an early exit only when noclobber triggers but not when outputthedata fails in any other way, that might look like:

set -C # enable noclobber exec 3>"$file
path" || exit # open output file set +C # disable noclobber for rest of the script outputthedata >&3 # actually run the subprocess with output to file exec 3>&- # close output file
March 31, 2026 Score: 0 Rep: 14,658 Quality: Medium Completeness: 80%

Recommended way

according to Charles Duffy is to set noclobber at the start of the sript

set -o noclobber

do something

outputthedata > "$filepath"

Hacky and not recommended:

Create the file if it does not exists right away

if [[ -e "$filepath" || -L "$filepath" ]]
then
    # Either throw an error, exit the script,
    # or something like that here.
    exit 1
else
    touch "$filepath"
fi

outputthedata > "$filepath"

Alternatively, the script PID can be written to the file instead of just touch. Last to write wins.

if [[ -e "$filepath" || -L "$filepath" ]]
then
    # Either throw an error, exit the script,
    # or something like that here.
    exit 1
else
    echo "$$" > "$filepath"
fi

read ownpid < "$filepath"

if [ "$ownpid" -eq $$ ]; then output
thedata > "$filepath" fi

March 31, 2026 Score: 0 Rep: 624 Quality: Low Completeness: 50%

You can avoid race conditions in this scenario by using file locking.
In my case, I used flock, which ensures that the entire read–modify–write sequence is executed atomically.

flock provides advisory locking where any number of processes may simultaneously hold a shared lock on a file. but only one process can hold an exclusive lock at a time.

if [[ -e "$filepath" || -L "$filepath" ]]; then ( flock -x 200 || { echo "Error: Could not acquire lock on $filepath" >&2 exit 1 } echo "Warning: File $filepath already exists" >&2 ) 200>"$lock_file" fi