30

If I have a command

$ ./script >> file.log

that gets called twice, with the second call occurring before the first one ends, what happens?

Does the first call get an exclusive lock on the output file? If so, does the second script fail when attempting to write, or does the shell accept the output (allowing the script to end) and throw an error?

Or does the log file get written to twice?

  • 1
    I don't know of any system that would lock the file by default. What is more likely is the two programs would end up interleaving their writes, since both would be in append mode. The results would be rather unpredictable. Instead of "hello world" you could get "hweolrllod". – jw013 Jul 07 '12 at 20:59

2 Answers2

22

Unix systems by and large avoid mandatory locks. There are a few cases where the kernel will lock a file against modifications by user programs, but not if it's merely being written by another program. No unix system will lock a file because a program is writing to it.

If you want concurrent instances of your script not to tread on each others' toes, you need to use an explicit locking mechanism such as flock lockfile.

When you open a file for appending, which >> does, each program is guaranteed to always write to the end of the file. So the multiple instances' output will never overwrite each other, and if they take turns to write, their output will be in the same order as the writes.

The bad thing that could happen is if one of the instances writes several chunks of output and expects them to come out together. Between consecutives writes by one instance, other instances may perform their own writes. For example, if instance 1 writes foo, then instance 2 writes hello and only then instance 2 writes bar, then the file will contain foohellobar.

A process effectively writes to the file when it calls the write system call. A call to write is atomic: each call to write writes a sequence of bytes that won't be interrupted by other programs. There is often a limit to how much data a single call to write will effectively write: for larger sizes, only the beginning of the data is written, and the application must call write again. Furthermore, many programs perform buffering: they accumulate data in a memory area, then write this data out in one chunk. Some programs flush the output buffer after a complete line or other meaningful separation. With such programs, you can expect whole lines to be uninterrupted, as long as they aren't too long (up to a few kilobytes; this depends on the OS). If the program does not flush at meaningful spots, but only based on the buffer size, you might see something like 4kB from one instance, then 4kB from another instance, then again 4kB from the first instance and so on.

17

Since you're using >>, which means append, each line of output from each instance will be appended in the order it occurred.

If your script output prints 1\n through 5\n with a one second delay between each and instance two is started 2.5 seconds later you'll get this:

1
2
1
3
2
4
3
5
4
5

So to answer your question: No.

bahamat
  • 39,666
  • 4
  • 75
  • 104