使用>>将多个并行进程的输出传输到一个文件是否安全?

我正在从网上抓取数据,而且我有几个并行的刮板处理程序。

我希望每个这些进程的输出结束在同一个文件中。 只要文本行保持完整,不要混淆在一起,行的顺序并不重要。 在UNIX中,我可以使用>>操作符将每个进程的输出传送到同一个文件吗?

不,不保证线路保持完整。 他们可以混在一起。

从根据liori的回答搜索我发现这个 :

写入{PIPE_BUF}个字节或更少的请求不应与来自其他进程写入同一管道的数据交错。 大于{PIPE_BUF}字节的写入可能会在任意边界上与其他进程的写入交错,无论文件状态标志的O_NONBLOCK标志是否被设置。

所以比{PIPE_BUF}字节长的行不能保证保持不变。

一个可能有趣的事情,你可以做的是使用GNU平行: http ://www.gnu.org/s/parallel/例如,如果你是蜘蛛网站:

stackoverflow.com, stackexchange.com, fogcreek.com 

你可以做这样的事情

 (echo stackoverflow.com; echo stackexchange.com; echo fogcreek.com) | parallel -k your_spider_script 

并且输出被并行缓存,并且由于-k选项按照上面的站点列表的顺序返回给您。 一个真实的例子(基本上从第二个平行的screencast复制):

  ~ $ (echo stackoverflow.com; echo stackexchange.com; echo fogcreek.com) | parallel -k ping -c 1 {} PING stackoverflow.com (64.34.119.12): 56 data bytes --- stackoverflow.com ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss PING stackexchange.com (64.34.119.12): 56 data bytes --- stackexchange.com ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss PING fogcreek.com (64.34.80.170): 56 data bytes 64 bytes from 64.34.80.170: icmp_seq=0 ttl=250 time=23.961 ms --- fogcreek.com ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 23.961/23.961/23.961/0.000 ms 

无论如何,ymmv

一般来说,不。

在Linux上这可能是有可能的,只要满足两个条件:每行写入一个操作,并且行不超过PIPE_SIZE(通常与PAGE_SIZE相同,通常为4096)。 但是…我不会指望那个; 这种行为可能会改变。

最好使用某种真正的日志机制,比如syslog。

你需要确保你在单一的写操作中写完整行(所以如果你使用某种形式的stdio,你需要设置行缓存至少是你最长的行的长度可以输出。)由于shell使用O_APPEND进行>>重定向,那么所有的写入操作都会自动附加到文件中,而不需要进一步操作。

使用临时文件并将它们连接在一起。 这是做你想做的唯一安全的方法,并且将会(可能)以这种方式忽略性能损失。 如果性能确实是一个问题,请确保您的/ tmp目录是基于RAM的文件系统,并将您的临时文件放在那里。 这样,临时文件就被存储在RAM中而不是存储在硬盘上,所以读/写它们几乎是即时的。

当然不是,我有一个日志管理脚本,我认为这个工作,它的确工作,直到我把它移动到一个负载下的生产服务器。 不是一个美好的一天…但基本上,你最终有时完全混合了线。

如果我试图从多个来源捕获,那么有一个多文件“纸路径”是更简单(更容易调试),如果我需要一个全面的日志文件,根据时间戳连接(您正在使用的时间 – 邮票,对吗?)还是像liori所说的那样,syslog。

简而言之,不。 >>不尊重多个进程。

除了使用临时文件的想法之外,您还可以使用某种聚合过程,尽管您仍然需要确保您的写入是原子的。

用管道日志记录来思考Apache2(如果你觉得雄心勃勃的话,就像在管道的另一端传播一样东西)。 这是它的方法,多个线程/进程共享一个日志进程。

如上所述,这是相当黑客,但工作得很好=)

 ( ping stackoverflow.com & ping stackexchange.com & ping fogcreek.com ) | cat 

与“>>”相同的东西:

 ( ping stackoverflow.com & ping stackexchange.com & ping fogcreek.com ) >> log 

并在最后一个exec上保存一个进程:

 ( ping stackoverflow.com & ping stackexchange.com & exec ping fogcreek.com ) | cat