Makefile 执行[FILE1-ot FILE2]会在make和shell中产生不同的结果

Makefile 执行[FILE1-ot FILE2]会在make和shell中产生不同的结果,makefile,Makefile,从中,我们可以说,如果FILE1早于FILE2,或者如果FILE2存在而FILE1不存在,则FILE1将生成True。如果FILE1不存在且FILE2存在,则在shell上执行此命令将返回True。然而,当我在make脚本中使用此选项时,只要FILE1不存在并且FILE2存在,它就会产生False。准确地说,我在make和shell脚本中使用了以下命令: [FILE1-ot FILE2]&&echo 1 | | echo 0 在shell上运行此命令时,无论何时都会返回1。但是,仅当FILE1存

从中,我们可以说,如果
FILE1
早于
FILE2
,或者如果
FILE2
存在而
FILE1
不存在,则
FILE1
将生成True。如果
FILE1
不存在且
FILE2
存在,则在shell上执行此命令将返回True。然而,当我在make脚本中使用此选项时,只要
FILE1
不存在并且
FILE2
存在,它就会产生False。准确地说,我在make和shell脚本中使用了以下命令:

[FILE1-ot FILE2]&&echo 1 | | echo 0

在shell上运行此命令时,无论何时都会返回1。但是,仅当
FILE1
存在并且被发现早于
FILE2
时,通过make运行此命令才会产生1。在其他情况下,即当未发现
FILE1
早于
FILE2
FILE1
不存在且存在
FILE2
时,上述命令在我的生成脚本中生成0。注意,在我的make脚本中,我将上述命令的结果存储在一个全局变量中。此全局变量稍后由条件变量在其中一个配方中使用

所以,我想知道这是make中的一个bug/特性,还是我这边的一个可能问题(由于一些打字错误或其他可能的错误源)

注意:我正在Ubuntu 18.04.3上使用GNU Make 4.1(在脚本中)尝试这个实验:

在我测试的情况下:当文件1不存在且文件2确实存在时:

#!/bin/sh

[ file1 -ot file2 ] && echo "file1 older" || echo "file2 older"
产生文件2旧版本

#!/bin/bash

[ file1 -ot file2 ] && echo "file1 older" || echo "file2 older"
生成旧文件1

默认情况下,make将使用#/bin/sh作为shell,您可以在makefile中通过:
shell=/bin/bash
来更改它


我不知道这有什么不同-它只是sh和bash之间的不同实现…

shell默认使用的不是bash。这也许可以解释你观察到的差异。你应该用已知文件和Makefile中的硬连接文件名创建一个非常简单的示例,这样每个人都可以重现你观察到的内容。我无法重现你的问题,GNU make 3.81、GNU make 4.3、bourne shell和bash(4个测试)。您的Makefile中可能有一个bug。@RenaudPacalet我可以使用默认的make版本复制运行Ubuntu18.04.2 LTS的版本。但我认为你在正确的轨道上——sh和def之间存在差异bash@code_fodder非常有趣,您可以添加详细信息(版本,Makefile…)@RenaudPacalet Ubuntu 18.04.2 LTS,GNU Make 4.1,GNU bash,版本4.4.19(1)-发布(x86_64-pc-linux-GNU)。你试过下面的实验了吗想看看你是否有不同吗如果您这样做了,那么您可以尝试更改makefile中的默认SHELL,看看这是否会有所不同——只是出于好奇,而不是出于任何原因:)“我不知道为什么会有所不同——这只是sh和bash之间的一个不同实现……”很可能,
-ot
不是POSIX测试的一部分,所以不同的SHELL(或二进制文件)可能有不同的行为。IIRC Ubuntu的
/bin/sh
是破折号,破折号的
-ot
是“如果file1和file2存在并且file1比file2旧,则为True”。谢谢您的回答。我的情况也不一样。如果存在
file1
,则bash和sh的行为类似。然而,当
file1
不存在时,就会弹出它们之间的差异。这似乎是Bash(显然是GNU-Test?)和其他人之间的差异:Ubuntu的
sh
dash
,它与zsh和bsd-Test匹配:
-ot
如果两个文件都存在并且file1比file2旧,则为true。