写单线路时回音原子 [英] Is echo atomic when writing single lines

查看:79
本文介绍了写单线路时回音原子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在试图让一个脚本编写输出从其他正常启动命令到日志文件中。该脚本会写它自己的信息到日志文件中使用的回声,有一个方法,我可以管系从其他程序。

I am currently trying to get a script to write output from other started commands correctly into a log file. The script will write it's own messages to the log file using echo and there is a method to which I can pipe the lines from the other program.

主要的问题是,它产生输出程序在后台启动,所以我的功能,它的读取可能concurently写入日志文件。难道这是一个问题吗?回声总是只写一行,所以它不应该是很难确保原子。不过,我已经看过在谷歌,我没有发现任何方式,以确保它实际上是原子的。

The main problem is, that the program which produces the output is started in the background, so my function that does the read may write concurently to the logfile. Could this be a problem? Echo always only writes a single line, so it should not be to hard to ensure atomicity. However I have looked in google and I have found no way to make sure it actually is atomic.

下面是当前的脚本:

LOG_FILE=/path/to/logfile

write_log() {
  echo "$(date +%Y%m%d%H%M%S);$1" >> ${LOG_FILE}
}

write_output() {
  while read data; do
    write_log "Message from SUB process: [ $data ]"
  done
}

write_log "Script started"
# do some stuff
call_complicated_program 2>&1 | write_output &
SUB_PID=$!
#do some more stuff
write_log "Script exiting"
wait $SUB_PID

正如你所看到的,该脚本可能在它自己的作为,因为重定向输出的同时编写为好。莫非在文件中这个事业的Havok?

As you can see, the script might write both on it's own as well as because of redirected output. Could this cause havok in the file?

推荐答案

回声就在一个简单的包装写 (这是一个简化;请参阅下面的血淋淋的细节编辑),因此,以确定是否回音是原子,它抬头写的是有用的。从统一UNIX规范

echo just a simple wrapper around write (this is a simplification; see edit below for the gory details), so to determine if echo is atomic, it's useful to look up write. From the single UNIX specification:

原子/非原子:写是原子,如果写在一个操作中的全部量的不与来自任何其它处理数据交织。当有多个作家将数据发送到一个单一的阅读器,这非常有用。应用程序需要知道一个写请求可以是多大预计将进行atomically.This最大称为{} PIPE_BUF。 Thisvolume IEEE标准1003.1-2001的不说无论是写请求超过{} PIPE_BUF字节是原子,但需要的{} PIPE_BUF或更少的字节写入应是原子的。

Atomic/non-atomic: A write is atomic if the whole amount written in one operation is not interleaved with data from any other process. This is useful when there are multiple writers sending data to a single reader. Applications need to know how large a write request can be expected to be performed atomically.This maximum is called {PIPE_BUF}. Thisvolume of IEEE Std 1003.1-2001 does not say whether write requests for more than {PIPE_BUF} bytes are atomic, but requires that writes of {PIPE_BUF}or fewer bytes shall be atomic.

您可以检查 PIPE_BUF 您的系统上用一个简单的C程序。如果你只是打印输出的单行线,这不是可笑的长,它应该是原子的。

You can check PIPE_BUF on your system with a simple C program. If you're just printing a single line of output, that is not ridiculously long, it should be atomic.

下面是一个简单的程序来检查的值 PIPE_BUF

Here is a simple program to check the value of PIPE_BUF:

#include <limits.h>
#include <stdio.h>

int main(void) {
  printf("%d\n", PIPE_BUF);

  return 0;
}

在Mac OS X上,这给了我512(参数最小允许值 PIPE_BUF )。在Linux上,我得到4096所以,如果你的线是相当长的,请务必检查其系统有问题的。

On Mac OS X, that gives me 512 (the minimum allowed value for PIPE_BUF). On Linux, I get 4096. So if your lines are fairly long, make sure you check it on the system in question.

修改添加:我决定检查在Bash中回声 ,实施以确认它会以原子打印​​。原来,回声使用的putchar 的printf 视您是否使用 -e 选项。这些被缓冲的标准输入输出操作,这意味着它们填满一个缓冲区,实际上它写出来,只有当达到一个换行符(以行缓冲模式),缓冲区已满(块缓冲模式),或者你明确地冲洗与 fflush 的输出。默认情况下,数据流将在线路缓冲模式,如果它是一个交互式终端,和块缓冲模式,如果它是任何其它文件。击不落缓冲类型,所以你的日志文件,它应该默认阻止的缓冲模式。在随后结束回声内置,猛砸调用 fflush 刷新输出流。因此,输出将始终在年底刷新回声,但如果它不适合入缓冲区可以更早地刷新。

edit to add: I decided to check the implementation of echo in Bash, to confirm that it will print atomically. It turns out, echo uses putchar or printf depending on whether you use the -e option. These are buffered stdio operations, which means that they fill up a buffer, and actually write it out only when a newline is reached (in line-buffered mode), the buffer is filled (in block-buffered mode), or you explicitly flush the output with fflush. By default, a stream will be in line buffered mode if it is an interactive terminal, and block buffered mode if it is any other file. Bash never sets the buffering type, so for your log file, it should default to block buffering mode. At then end of the echo builtin, Bash calls fflush to flush the output stream. Thus, the output will always be flushed at the end of echo, but may be flushed earlier if it doesn't fit into the buffer.

使用可 BUFSIZ ,虽然它可能是不同的缓冲区的大小; BUFSIZ 是默认的大小,如果你设置缓冲区显式地使用则setbuf ,但没有可移植的方法来确定实际的您的缓冲区的大小。还有什么 BUFSIZ 是没有可移植的指导方针,但是当我测试了它在Mac OS X和Linux,它是的PIPE_BUF <大小的两倍/ code>。

The size of the buffer used may be BUFSIZ, though it may be different; BUFSIZ is the default size if you set the buffer explicitly using setbuf, but there's no portable way to determine the actual the size of your buffer. There are also no portable guidelines for what BUFSIZ is, but when I tested it on Mac OS X and Linux, it was twice the size of PIPE_BUF.

这是什么意思呢?由于输出回声的所有缓存,它不会真正调用,直到缓冲区填满或 fflush 被调用。在这一点上,输出应该写的,我上面提到的原子性保障应适用。如果标准输出缓冲区的大小比 PIPE_BUF 大,那么 PIPE_BUF 将是可以写出最小的原子单位。如果 PIPE_BUF 比标准输出缓冲区大小,则该流将写缓存出来的时候,缓冲区已满。

What does this all mean? Since the output of echo is all buffered, it won't actually call the write until the buffer is filled or fflush is called. At that point, the output should be written, and the atomicity guarantee I mentioned above should apply. If the stdout buffer size is larger than PIPE_BUF, then PIPE_BUF will be the smallest atomic unit that can be written out. If PIPE_BUF is larger than the stdout buffer size, then the stream will write the buffer out when the buffer fills up.

因此​​,回声只保证原子写短序列比 PIPE_BUF 的更小的尺寸标准输出缓冲区,这是最有可能的 BUFSIZ 。在大多数系统中, BUFSIZ 较大的 PIPE_BUF

So, echo is only guaranteed to atomically write sequences shorter than the smaller of PIPE_BUF and the size of the stdout buffer, which is most likely BUFSIZ. On most systems, BUFSIZ is larger that PIPE_BUF.

TL;博士回声将原子输出线,只要这些线路足够短。在现代系统中,你可能是安全的最多512个字节,但它无法确定可移植的限制。

tl;dr: echo will atomically output lines, as long as those lines are short enough. On modern systems, you're probably safe up to 512 bytes, but it's not possible to determine the limit portably.

这篇关于写单线路时回音原子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆