Linux用awk和tee写入同一个文件:非常奇怪的行为



我试图做一些不寻常的事情,并在 Unix Shell 脚本中写出这个问题时覆盖意外的新行上的相同文件 只是出于好奇

我发现在某些尝试中我可以开球> to_same_file并且它的工作原理就像您在第一次尝试中看到的那样,然后随后的尝试生成了一个空文件,我的假设是,这一定与处理时间有关。这意味着在第一次尝试时,需要更长的时间才能到达tee并有时间进行I/O,因为在其他尝试中发生得更快,并且没有机会及时写入文件。只是有兴趣了解为什么会发生这种奇怪的行为

me@desktop:~/$ cp 2.csv 1.csv
me@desktop:~/$ cat 1.csv
ABCD89A, Admin, shop, Stall Count, 2014-01-06 09:00:00, 0
ABCD89N, Admin, shop, Stall Count, 2014-01-06 09:00:00, 0
me@desktop:~/$ awk  -F"," '{ 
     timestamp=$5;  
     gsub(":"," ",timestamp); 
     gsub("-"," ",timestamp);   
     EPOCH=(mktime(timestamp))
     } 
     {
      print $0","EPOCH
      }' 1.csv  2>&1 | tee > 1.csv
me@desktop:~/$ cat 1.csv
ABCD89A, Admin, shop, Stall Count, 2014-01-06 09:00:00, 0,1388998800
ABCD89N, Admin, shop, Stall Count, 2014-01-06 09:00:00, 0,1388998800
me@desktop:~/$ cp 2.csv 1.csv
me@desktop:~/$ cat 1.csv 
ABCD89A, Admin, shop, Stall Count, 2014-01-06 09:00:00, 0
ABCD89N, Admin, shop, Stall Count, 2014-01-06 09:00:00, 0
me@desktop:~/$ awk  -F"," '{ 
     timestamp=$5;  
     gsub(":"," ",timestamp); 
     gsub("-"," ",timestamp);   
     EPOCH=(mktime(timestamp))
     } 
     {
      print $0","EPOCH
      }' 1.csv  2>&1 | tee > 1.csv
me@desktop:~/$ cat 1.csv 
me@desktop:~/$ cp 2.csv 1.csv
me@desktop:~/$ awk  -F"," '{ 
     timestamp=$5;  
     gsub(":"," ",timestamp); 
     gsub("-"," ",timestamp);   
     EPOCH=(mktime(timestamp))
     } 
     {
      print $0","EPOCH
      }' 1.csv  2>&1 | tee > 1.csv
me@desktop:~/$ cat 1.csv 
me@desktop:~/$ cp 2.csv 1.csv
me@desktop:~/$ cat 1.csv 
ABCD89A, Admin, shop, Stall Count, 2014-01-06 09:00:00, 0
ABCD89N, Admin, shop, Stall Count, 2014-01-06 09:00:00, 0
me@desktop:~/$ awk  -F"," '{ 
     timestamp=$5;  
     gsub(":"," ",timestamp); 
     gsub("-"," ",timestamp);   
     EPOCH=(mktime(timestamp))
     } 
     {
      print $0","EPOCH
      }' 1.csv  2>&1 | tee -a > 1.csv
me@desktop:~/$ cat 1.csv 
me@desktop:~/$ 

一个具有相同问题的小型自包含测试用例是这样的:

cat file | tee > file

此管道由并行运行的两个部分组成。

cat file尝试打开并从文件中读取。

tee > file尝试截断该文件。

根据文件是(部分)先读取还是先截断,您将获得部分或全部数据,或者只是一个空文件。

您所做的是在awktee之间创建竞争条件。awk进程打开1.csv进行读取,同时tee被重定向到另一个进程中的1.csv

正如比赛条件的性质一样,结果是随机的,取决于谁先到达那里。

为了安全地执行此操作,您需要将其保存到新文件中或使用类似 sponge .

相关内容

  • 没有找到相关文章

最新更新