3

ShellCheck show the following error for this line of code:

printf '%d' $(($(< "$1") + 1)) > "$1"

Make sure not to read and write the same file in the same pipeline

Is this really a problem? Could reading and writing the same file result in a race condition?

helpermethod
  • 1,982

2 Answers2

3

Yes, this is a problem, you can never read and write from/to the same pipe. Think of it this way: writing a file would set it to start as empty, and then reading from it would not yield anything.

proycon
  • 314
  • 1
  • 6
  • I was under the impression that $(< "$1") would read the file as a whole, no? – helpermethod Sep 24 '15 at 14:41
  • 1
    Actually, you're right indeed. Sorry, I glossed over your $(< "$1" ) syntax which indeed delegates it to a subshell, so the pipe is closed before output starts. It works and the syntax checker is wrong. – proycon Sep 24 '15 at 15:03
  • 1
    This problem is the exact reason the sponge utility was invented. It will be in your moreutils package on most Linux distributions. – Akinos Sep 25 '15 at 04:16
2

Yes, reading and writing from the same file in parallel could result in a race condition. An input and an output redirection for the same file on the same command would truncate the file before starting to read it.

But no, this isn't what's happening here. It's a false positive in Shellcheck. Here the redirection is inside an arithmetic expression. All substitutions (arithmetic, variable, command, as well as splitting and globbing) are performed before redirections are executed. So at the time > "$1" opens the file, the reading bit is finished.