追加输出文件的时候奇怪的错误 [英] Strange bug when appending output to file

查看:96
本文介绍了追加输出文件的时候奇怪的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有追加在bash以文件的形式获取文本即使我告诉它删除追加时,奇怪的错误。

我有一个bash脚本,我做以下

 回声运行程序> foo.txt的
./fortran_program>> foo.txt的

该计划fortran_program(它的一个精简版,让相同的结果)是:

 程序的主
写一个'
写(*,*)'B'
程序结束

这应执行后给我运行程序AB 在foo.txt的。不过我觉得操作B 代替原文已被覆盖和 A 不包括在内。

我做了 strace的-f ./script ,发现下面的输出,看起来相关的:

  ...
[PID 36681]打开(foo.txt的,O_WRONLY | O_CREAT | O_APPEND,0666)= 3
[PID 36681] dup2(3,1)= 1
[PID 36681]关闭(3)= 0
...
[PID 34260]写(1,A \\ N,3)= 3
[PID 34260] lseek的(1,0,SEEK_CUR)= 3
[PID 34260] ftruncate(1,3)= 0
[PID 34260]写(1,B \\ N,3)= 3
...

从我十分有限的这种理解似乎 A 写入文件,然后 lseek的被称为这给该文件只有3个字符(长度相同的第一个字符串我尝试写),然后 ftruncate 截断它在3个字符(即运行),然后写入 B 该文件。

在C以下程序(回声运行程序> foo.txt的; ./c_program )抄录所以现在看来​​,这不只是FORTRAN相关行为(虽然只有ifort编译code给出上述错误)

 #包括LT&;&unistd.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / stat.h>
#包括LT&;&fcntl.h GT;诠释主(){
  INT N,F;
  F =打开(foo.txt的,O_WRONLY | O_CREAT | O_APPEND,0666);
  写(F,A \\ N,3);
  N = lseek的(F,0,SEEK_CUR);
  ftruncate(F,N);
  写(F,B \\ N,3);
}

但奇怪的是,当我运行code上面我的笔记本电脑确实在意料之中的事情,给我运行程序AB 所以逻辑上似乎 lseek的使我使用群集上的问题,但我知道一点吧(我不知道如何解决它),所以我问在这里。


  

为什么会出现这种情况,最重要的是:?有没有办法解决这个问题。


这是很烦人的,因为为了避免它,我需要做一个临时文件和管道从运行到这个输出,然后condencate与临时文件的原始文件之后,以获得所需的输出为 foo.txt的

系统规格在那里我有这个问题:

  ifort 14.0.2 20140120
GCC 4.4.7 20120313
Linux集群2.6.32-431.29.2.el6.x86_64#1 SMP太阳7月27日15时55分46秒美国东部时间2014年的x86_64 x86_64的x86_64的GNU / Linux的

和它的工作。

  GCC 4.8.5
达尔文笔记本13.4.0 Darwin内核版本13.4.0:太阳8月17日19点50分11秒PDT 2014年;根:XNU-2422.115.4〜1 / RELEASE_X86_64 x86_64的


解决方案

我的Fortran语言很生疏,但我认为,在默认情况下Fortran语言将每个作为一个单独的记录,这是导致新线(和寻求 - 这似乎是一个越野车对我来说,太)。

如果你想用晚餐preSS这种行为,这可能是一个有点接近你要找的是什么:

 程序的主
写(*,100,事先='无')'A'
写(*,100,事先='无')'B'
100格式(A)
程序结束

I have a strange bug when appending to file in bash where text gets deleted even though I’m telling it to append.

I have a bash-script where I do the following

echo "Run program" > foo.txt
./fortran_program >> foo.txt

The program fortran_program (a stripped down version of it that gives the same result) is:

program main 
write(*,*) 'A'
write(*,*) 'B'
end program

This should give me Run program AB in foo.txt after the execution. However I find Run B instead so the original text has been overwritten and A is not included.

I did strace -f ./script and found the following output that looks relevant:

...
[pid 36681] open("foo.txt", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
[pid 36681] dup2(3, 1)                  = 1
[pid 36681] close(3)                    = 0
...
[pid 34260] write(1, " A\n", 3)         = 3
[pid 34260] lseek(1, 0, SEEK_CUR)       = 3
[pid 34260] ftruncate(1, 3)             = 0
[pid 34260] write(1, " B\n", 3)         = 3
...

From my very limited understanding of this it seems that A is written to the file, then lseek is called which gives that the file is only 3 characters long (same length as the first string I try to write) and then ftruncate truncates it at 3 characters (i.e. Run) and then writes B to the file.

The following program in c (echo "Run program" > foo.txt; ./c_program) reproduces the behaviour so it seems it is not just fortran related (though only ifort compiled code gives the error above)

#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main(){
  int n, f;
  f = open("foo.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
  write(f," A\n",3);
  n = lseek(f,0,SEEK_CUR);
  ftruncate(f,n);
  write(f," B\n",3);
}

The strange thing is that when I run the code above on my laptop it does the expected thing and gives me Run Program AB so it seems logical that lseek causes the problem on the cluster I use, but I know to little of it (and I have no idea how to fix it) so I'm asking it here.

Why does this happen and most importantly: is there a way to fix this?

This is quite annoying since to avoid it I need to make a temp file and pipe the output from the run into this and then condencate the original file with the temp-file afterwards to get the desired output to foo.txt.

System specifications where I have the problem:

ifort 14.0.2 20140120
gcc 4.4.7 20120313
Linux cluster 2.6.32-431.29.2.el6.x86_64 #1 SMP Sun Jul 27 15:55:46 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux

and where it's working

gcc 4.8.5
Darwin laptop 13.4.0 Darwin Kernel Version 13.4.0: Sun Aug 17 19:50:11 PDT 2014; root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64

解决方案

My Fortran is very rusty, but I think that by default Fortran treats each write as a separate record, which is resulting in the new lines (and the seeks? - which seems a buggy to me, too).

If you want to suppress that behavior, this might be a little closer to what you're looking for:

program main 
write(*,100, advance='no') 'A'
write(*,100, advance='no') 'B'
100 format (A)
end program

这篇关于追加输出文件的时候奇怪的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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