How to raise and take care of shell scripts: handle files

Read from and write into files

It's an ordinary problem: You want to modify a file, the modified content should be stored in the same file. Sometimes you can read hints like: tr -d '\r' <file >file. Don't do that! You could hurt the file, mutilate or empty it. Such constructions are a kind of lottery with similar chances of winning. You don't know the order, how the program (or the shell) opens and closes file descriptors, how files are read and written (the block size they use), how the underlying file system driver caches, when the buffers are flushed - you see: you don't know anything ;-) Stay away from such "solutions".

Some programs allow the "in place" editing of files, for example sed -i. Besides that you probably can "in place" edit files using some programs, if you take care of the circumstances: If you use awk, it should be harmless to write back to the file in the END block (reading the input is finished at this time) - store the content you want to write in program variables or arrays in the meantime. But I give no warranty for this hint!

The best way in my opinion is the use of temporary files, in a safe way like this:

  # create a temporary file with a unique name, exit in case of an error
  TMP_FILE=`mktemp` || exit 1
  # ensure, that the file will be deleted in case of program errors
  trap "rm -f $TMP_FILE 2>/dev/null; exit 1" 1 2 3 15 ERR
  # write the modified content into the temporary file,
  # move it to the source file name when successful
  tr -d '\r' </path/to/my/source_file >$TMP_FILE && mv $TMP_FILE /path/to/my/source_file

You'll find more about trap in the next chapter and where else? Yeah - in the bash manual.