cp: 无法创建普通文件 : 文件已存在
背景
碰到一个偶现的编译出错问题,如图
报错的信息是
cp: 无法创建普通文件"xxx": 文件已存在
排查原因
看了下 Makefile
,这句非常简单,就是 cp ./xxx ../xxx
而已,本身没什么问题。
那再结合上下文出现的打印,一个异常之处就是 Makfeile
被并行重复执行了,猜测是并行导致 cp
操作出错。
只考虑解决问题,那无疑是修改外层 Makefile
,避免此处被并行重复执行,至少这句 cp
不要被并行,就可以解决了。
但为什么 cp
并行执行会出错呢?如果在另外的场景下确实有并行执行cp
的可能,有没有办法规避这个错误呢?这就得探究下了。
单独执行 cp
,默认的行为就是覆盖已存在的文件,并不会因为 “文件已存在” 这样的原因出错,随便做下实验,touch a b; cp a b
就可以确认正常是不会报错的。
那问题还是得结合并行来分析,碰到这种情况,要么是从搜索资料获得提示,要么就是实践出真知,自己设计一个可快速复现的方式,然后使用调试工具来追踪问题发生时的具体情况。
具体到这个问题,我是搜索到相同的stackexchange问题,那就省点工夫不用自己去复现分析了。
这里插下题外话,搜索优先使用google
,对于中文报错信息查不到的可改成英文查询。例如中文的 cp: 无法创建普通文件 文件已存在
就不好找到答案,换成 cp cannot create regular file file exists
就好找了。(只敲一部分,搜索引擎就能提示完整的信息)
stackexchage
上给出了一个脚本,用于复现问题并使用 strace
将追踪的系统调用记录下来
#!/bin/bash
touch a
f() {
while true; do
rm -f b
strace -o /tmp/cp${BASHPID}.trace cp a b || break
done
}
cleanup() {
kill -9 %1 %2
}
f &
f &
trap cleanup exit
wait
附上我自己的实验结果,可以看出cp
的实现上,会先用stat
来判断目标文件b
是否存在,如果不存在则会使用 open("b", O_WRONLY|O_CREAT|O_EXCL, 0664)
来创建目标文件并将源文件写入目标文件,完成复制。
那么如果两个 cp
并发,就可能出现
cp1 cp2
stat判断b不存在
stat判断b不存在
open成功,创建文件b
open失败,因为此时文件已经被cp1创建好了
从 strace
的 log
看到的就是
由于 cp
不是原子的,如果两个 cp
刚好几乎同时执行,则可能两个 cp
的stat
都判断到文件不存在,那最终只有一个 cp
能创建文件,另一个就失败了。
顺便看看,文件存在和不存在的open
参数差异
解决办法
既然两个cp
同时执行会出错,那就加锁呗。
如果所有调用 cp
的地方都是我们可控的,那劝告锁就足够了,在 shell
中可以直接使用 flock
。
约定好一个文件锁x
, 将原来的cp a b
改成 flock x cp a b
即可。
例如正常在两个控制台中,执行top
是可以并行的,但如果改成执行 flock /tmp/toplock top
,那就只有控制台1
会执行top
,控制台2
则处于等待文件锁的状态。此时若控制台1
退出top
,则控制台2
获得锁,开始执行top
。
更多文件锁的细节,可以看看 man flock
。
blog: https://www.cnblogs.com/zqb-all/p/12942556.html
公众号:https://sourl.cn/S42YSr
cp: 无法创建普通文件 : 文件已存在的更多相关文章
- [转]iOS学习笔记(2)--Xcode6.1创建仅xib文件无storyboard的hello world应用
转载地址:http://www.mamicode.com/info-detail-514151.html 由于Xcode6之后,默认创建storyboard而非xib文件,而作为初学,了解xib的加载 ...
- iOS学习笔记(2)--Xcode6.1创建仅xib文件无storyboard的hello world应用
http://www.mamicode.com/info-detail-514151.html 由于Xcode6之后,默认创建storyboard而非xib文件,而作为初学,了解xib的加载原理很重要 ...
- JAVA之旅(二十八)——File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤
JAVA之旅(二十八)--File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤 我们可以继续了,今天说下File 一.File概述 文件的操作是非常 ...
- Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件
写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...
- [Swift]在Swift项目中创建桥接头文件,Swift文件和Objective-C文件相互调用
创建一个Swift项目[demo],以下内容Swift文件和Objective-C文件相互调用都是在Swift项目中. 一.Swift文件调用Objective-C文件 新建文件夹[SupportFi ...
- 【练习】Java中的读文件,文件的创建,写文件
前言 大家好,给大家带来Java中的读文件,文件的创建,写文件的概述,希望你们喜欢 读文件 public static void read(String path,String filename){ ...
- Excel催化剂开源第4波-ClickOnce部署要点之导入数字证书及创建EXCEL信任文件夹
Excel催化刘插件使用Clickonce的部署方式发布插件,以满足用户使用插件过程中,需要对插件进行功能升级时,可以无痛地自动更新推送新版本.但Clickonce部署,对用户环境有较大的要求,前期首 ...
- Java中的读文件,文件的创建,写文件
前言 大家好,我是 Vic,今天给大家带来Java中的读文件,文件的创建,写文件的概述,希望你们喜欢 示意图 读文件 public static void read(String path,Strin ...
- 为什么vue-cli创建的build文件下没有dev-server.js文件
在新版本的Vue开发中,通过vue-cli创建的build文件夹下面已经没有了旧版本中的dev-server.js文件新版本的vue已将dev-server.js与webpack.dev.conf.j ...
随机推荐
- Unity(GameObject)
####1. 这个方法用于发送一个数据到指定的方法中,第三个参数是是否强制接收 以下三种方法发送消息的形式,各有不同的效果,可以通过第一个参数指定要发送的方法名名,第二个是发送的参数值,第三个参数是是 ...
- VS中的生成和重新生成的区别
2019独角兽企业重金招聘Python工程师标准>>> 生成 在上次编译的基础上,只对改动过的文件重新生成,没有改动过的文件不会重新生成. 重新生成 对所有的文件都重新生成.如果引用 ...
- unittest 管理接口用例(数据分离-读取excel)
1.公共模块 ---> login.xls """ common (package) ---> ReadFile.py """ ...
- Java实现通过反射获取指定类的所有信息
package com.ljy; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.l ...
- 经典卷积神经网络算法(1):LeNet-5
.caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...
- bootstrap栅格系统的使用
bootstrap栅格系统的使用 bootstrap栅格系统的使用,主要分为四种方式 1.列组合 col-md-* 2.列偏移 col-md-offset-* 3.列嵌套 大列组合包含着小组合 4 ...
- 王颖奇 201771010129《面向对象程序设计(java)》第六周学习总结
实验六 继承定义与使用 实验时间 2018-9-28 1.目的与要求 理论部分: 继承(inheritance): 继承的特点:具有结构层次:子类继承了父类的域和方法. 主要内容: (1)类.子类.超 ...
- 一分钟html页面倒计时可精确到秒
<!doctype html> <html> <head> <meta charset="utf-8"> </head> ...
- 5G新基建到来,图扑推出智慧路灯三维可视化方案
前言 作为智慧城市的重要组成部分,智慧灯杆管理系统采用信息化.数字化手段,把路灯及城市景观照明等各种不同对象的监控和数据采集及处理融于一体, 为城市管理者进行城市管理.进行科学决策提供了强有力的手段. ...
- JPA---Spring-data-JPA---Hibernate
Spring Data JPA--搭建环境 版本---maven 3.6.3 <properties> <spring.version>5.2.5.RELEASE</s ...