The following alternative should do the trick:
TIMEOUT=10 # modify to your liking
tail -n 0 -f "$MS01_LOG_FILE" "$MS02_LOG_FILE" | while :
IFS= read -t $TIMEOUT -r line
# do your funny things here
First quoting from
help read (see bash reference manual for the builtin command "read")
Cause read to time out and return failure if a complete line of input (or a specified number of characters) is not read within
timeout seconds. timeout may be a decimal number with a fractional
portion following the decimal point. This option is only effective if
read is reading input from a terminal, pipe, or other special file; it
has no effect when reading from regular files. If read times out, read
saves any partial input read into the specified variable name. If
timeout is 0, read returns immediately, without trying to read and
data. The exit status is 0 if input is available on the specified file
descriptor, non-zero otherwise. The exit status is greater than 128 if
the timeout is exceeded.
Note that the exit status being greater than 128 for detecting a read timeout is not guaranteed between implementations (e.g. on my OS X's bash it is 1).
Now simply adding
-t $TIMEOUT to your initial script provides only one part of the solution since the broken pipe won't be detected until anything gets emitted from the tail pipe.
read into a endless while loop solves that issue.
Depending on what you want to do instead of
# do your funny things here you might now be confronted with the issue of escaping from that child process jail.
In that case check https://stackoverflow.com/questions/20558295/quit-from-pipe-in-bash