我试图做一些不寻常的事情,并在 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
尝试截断该文件。
根据文件是(部分)先读取还是先截断,您将获得部分或全部数据,或者只是一个空文件。
您所做的是在awk
和tee
之间创建竞争条件。awk
进程打开1.csv
进行读取,同时tee
被重定向到另一个进程中的1.csv
。
正如比赛条件的性质一样,结果是随机的,取决于谁先到达那里。
为了安全地执行此操作,您需要将其保存到新文件中或使用类似 sponge
.