Makefile中Curl命令未按顺序执行反而并发问题咨询
Makefile中curl并发下载的原因及解决办法
核心原因:Make与Shell的执行逻辑差异
你在zsh里用&&连接两个curl命令时,是在同一个Shell进程中串行执行——只有第一个curl执行完成且返回成功,才会触发第二个curl。但放到Makefile后出现并发,大概率是以下两种情况:
1. 将两个下载任务拆分为独立的Make目标
如果你的Makefile写法类似这样:
A.html: curl -o ./A.html https://myserv.com/script.php?file=A B.html: curl -o ./B.html https://myserv.com/script.php?file=B all: A.html B.html
Make的默认行为是并行处理无依赖关系的目标。由于A.html和B.html之间没有定义依赖关系,Make会同时启动两个Shell进程分别执行它们的下载命令,最终导致并发下载。
2. 同一目标下的命令拆分执行(或开启了并行模式)
如果把两个命令写在同一个目标下,但未合并到同一个Shell进程:
download: curl -o ./A.html https://myserv.com/script.php?file=A curl -o ./B.html https://myserv.com/script.php?file=B
正常情况下Make会按顺序执行这两行命令(完成第一个再启动第二个),但如果你使用了make -j这类并行参数,Make就会同时启动两个Shell进程执行这两行,进而引发并发。
解决办法
方法一:合并到同一个Shell串行执行
将两个命令用&&连接,并用反斜杠正确换行(注意反斜杠后不能有空格),让它们在同一个Shell进程中串行执行:
download: curl -o ./A.html https://myserv.com/script.php?file=A && \ curl -o ./B.html https://myserv.com/script.php?file=B
方法二:给目标添加依赖关系
如果想用Make的目标机制管理文件,给B.html添加对A.html的依赖,强制Make先完成A的下载再执行B的下载:
A.html: curl -o ./A.html https://myserv.com/script.php?file=A B.html: A.html curl -o ./B.html https://myserv.com/script.php?file=B all: B.html
内容的提问来源于stack exchange,提问作者tony_merguez
相关产品推荐
相关产品推荐

