重复创建指向同一文件的文件描述符,bash

重复创建指向同一文件的文件描述符,bash

如果我在 bash 中创建一个文件描述符并将其指向一个文件并将一些数据放入其中:

exec 5>>file
for i in {1..10000}; do
    echo "$i" >&5
done

文件描述符 5 保存打开的“文件”,每当我将数据写入该描述符时,它都会附加数据并保留其在文件中的当前位置。

如果我再次将同一描述符重新指向同一文件:

exec 5>>file

它是否关闭当前的 fd 并重新创建一个指向同一文件的新文件?那么下次我写入数据时,它必须先找到文件的末尾,然后再追加到末尾吗?或者,它是否足够聪明,能够意识到描述符已经指向该文件,并且不执行任何操作。低水平是怎么回事?

编辑:更具体地说,我使用文件描述符将数据记录到文件中以保持文件打开。一些相关位:

recv_udp    () {    # Receives a udp stream, timestamps and removes commas and the period from the seconds field, deletes blank lines.
        socat -L "$LOCKFILE" -u udp-recv:"$UDP_IN",reuseaddr STDIO | ts '%Y %j %H %M %.S' | sed -u -e 's/,/ /g' -e 's/\./ /' -e '/^$/d' &
        }

file_handle () {    # Points file descriptor 9 to the desired log file
        exec 9>>"$DATADIR"/"$CRUISEID"/"$STAMP"/"$STAMP"_"$JDY"_raw
        }

parse_lci90i    () {    # Parse lci90i winch controller mtnw2 data stream.
        echo "Started $STAMP $CRUISEID $(date +'%c')" >> "$LOGFILE"
        while read YR JDY HR MIN SEC uS GARBAGE GARBAGE TENS SPD LINE CHKSUM; do
            printf '%4.0f %03.0f %02.0f %02.0f %02.0f %.3s %s %.0f %.1f %.0f\n' "$YR" "$JDY" "$HR" "$MIN" "$SEC" "$uS" "$STAMP" "$SPD" "$LINE" "$TENS"
            check_path
            file_handle
            printf '%4.0f %03.0f %02.0f %02.0f %02.0f %.3s %s %.0f %.1f %.0f\n' "$YR" "$JDY" "$HR" "$MIN" "$SEC" "$uS" "$STAMP" "$SPD" "$LINE" "$TENS" >&9
        done
        }

Socat 读取 20hz udp feed 并通过进程替换将其泵入解析器。您可以在这里看到,每次读取一行数据时,文件描述符都会被重新创建。所以是的,我很好奇这是否比仅从解析器中获取标准输出并直接将 >> 放入日志文件更有效。

感谢到目前为止各位的回复,你们都很有见地。数据文件的文件名包含数据时间戳的儒略日,因此当日期更改时,日志文件每天都会滚动。

答案1

bash通过首先刷新标准文件描述符 1(输出)和 2(错误)来处理它们的重定向。除此之外,它没有执行任何特殊操作(不关心该文件描述符可能用于什么目的),只是调用dup2来建立一个新的到文件的连接。

只要您打开文件描述符,它就会通过一个文件描述符跟随同一个文件改名。但是,在文件重命名后打开新的文件描述符将写入新文件,而不是继续写入旧文件。同样,子进程写入旧文件将继续,直到描述符关闭

进一步阅读(源代码):

相关内容