Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Makefile编辑文件而不是创建文件_Makefile - Fatal编程技术网

使用Makefile编辑文件而不是创建文件

使用Makefile编辑文件而不是创建文件,makefile,Makefile,我正在考虑对我的开发设置使用Make进行小检查。我想做的一件事是在执行某些操作之前检查文件中是否存在特定的字符串。如果我想创建整个文件,它将是微不足道的 action: filename ... filename: echo 'blah' >> filename 但是如何将这种逻辑应用于动作,比如grep?我的依赖不是文件是否存在,而是文件的内容是否正确 我问的是Make,而不是像chef/puppet这样的其他解决方案。你可以在Make配方中运行任何shell命

我正在考虑对我的开发设置使用Make进行小检查。我想做的一件事是在执行某些操作之前检查文件中是否存在特定的字符串。如果我想创建整个文件,它将是微不足道的

action: filename
    ...

filename:
    echo 'blah' >> filename
但是如何将这种逻辑应用于动作,比如
grep
?我的依赖不是文件是否存在,而是文件的内容是否正确


我问的是Make,而不是像chef/puppet这样的其他解决方案。你可以在Make配方中运行任何shell命令。你想要多少就有多少

因此,如果您需要在执行其他操作之前运行
grep
,请执行该操作

请记住,配方中的每一行都在其自己的shell会话中运行,因此它们不会共享状态

因此:

action: filename
    ...

filename:
    grep -qw blah $@ || echo 'blah' > $@
filename
上运行
grep
(通过当前目标
$@
)查找整个单词并在第一次匹配时退出(
-q

如果
grep
发现
blah
则返回成功,
|
将短路,配方完成。如果
grep
失败,则将触发
|
并运行
echo

如果Y为真,您可能会尝试执行需要反向逻辑do X的操作:

filename:
    grep -qw blah $@ && echo blah2 > $@
但这并不正确。当
grep
失败时,
&
短路,并且
make
看到配方失败,并以错误退出
make
过程

你需要这个

filename:
    ! grep -qw blah $@ || echo blah2 > $@
颠倒逻辑,确保grep的“失败”在make方面被视为成功

在这个特定的例子中,如果“代码>文件名存在,那么该配方不会运行,因为它没有先决条件,所以<代码>使总是考虑它最新的。要解决这个问题,您需要为该文件提供一个先决条件,使其被视为过时。特别是一个


不过,对于这种情况,不要遵循关于
.PHONY
的建议
.PHONY
目标永远不应该是非
.PHONY
目标的先决条件。

您可以在make配方中运行所需的任何shell命令。你想要多少就有多少

因此,如果您需要在执行其他操作之前运行
grep
,请执行该操作

请记住,配方中的每一行都在其自己的shell会话中运行,因此它们不会共享状态

因此:

action: filename
    ...

filename:
    grep -qw blah $@ || echo 'blah' > $@
filename
上运行
grep
(通过当前目标
$@
)查找整个单词并在第一次匹配时退出(
-q

如果
grep
发现
blah
则返回成功,
|
将短路,配方完成。如果
grep
失败,则将触发
|
并运行
echo

如果Y为真,您可能会尝试执行需要反向逻辑do X的操作:

filename:
    grep -qw blah $@ && echo blah2 > $@
但这并不正确。当
grep
失败时,
&
短路,并且
make
看到配方失败,并以错误退出
make
过程

你需要这个

filename:
    ! grep -qw blah $@ || echo blah2 > $@
颠倒逻辑,确保grep的“失败”在make方面被视为成功

在这个特定的例子中,如果“代码>文件名存在,那么该配方不会运行,因为它没有先决条件,所以<代码>使总是考虑它最新的。要解决这个问题,您需要为该文件提供一个先决条件,使其被视为过时。特别是一个


不过,对于这种情况,不要遵循关于
.PHONY
的建议
.PHONY
目标不应该是非
.PHONY
目标的先决条件。

您可以在目标的配方中添加测试(如Etan在我完成此答案之前发布的…)。如果您确实想使用just make logic执行此操作,您可以按照以下方式执行操作:

actions: $(if $(shell grep -q $$string filename && echo y),filename,)

filename:
    echo blah >> $@

如果filename包含字符串,则将存在一个
actions:filename
依赖项,并且在生成操作时将生成filename。请注意,虽然这将检查在解析makefile时该字符串是否存在于filename中——如果在此makefile中生成或修改了filename,则不会影响操作是否运行。如果您想在覆盖文件之前进行测试,那么可以在配方本身中使用bash If语句。

您可以在目标配方中添加测试(正如我完成此答案之前Etan发布的…)。如果您确实想使用just make logic执行此操作,您可以按照以下方式执行操作:

actions: $(if $(shell grep -q $$string filename && echo y),filename,)

filename:
    echo blah >> $@

如果filename包含字符串,则将存在一个
actions:filename
依赖项,并且在生成操作时将生成filename。请注意,虽然这将检查在解析makefile时该字符串是否存在于filename中——如果在此makefile中生成或修改了filename,则不会影响操作是否运行。如果您想在覆盖文件之前进行测试,那么可以在配方本身中使用bash If语句。

扩展@john编写的内容,我得到了以下结果:

TEST_FILE=filename
.PHONY: ${TEST_FILE}
string=testing

filecheck=$(shell grep -qw ${string} ${TEST_FILE} || echo ${TEST_FILE})

all: ${filecheck}

${TEST_FILE}:
    echo 'changing the file'
    echo ${string} >> ${TEST_FILE}

这里我正在操作的文件是一个
.PHONY
目标。我认为这没关系,因为我实际上不是在创建文件,只是在修改它。如果文件不存在,或者没有所需字符串,这将起作用。

扩展@john编写的内容,我得到了以下工作:

TEST_FILE=filename
.PHONY: ${TEST_FILE}
string=testing

filecheck=$(shell grep -qw ${string} ${TEST_FILE} || echo ${TEST_FILE})

all: ${filecheck}

${TEST_FILE}:
    echo 'changing the file'
    echo ${string} >> ${TEST_FILE}

这里我正在操作的文件是一个
.PHONY
目标。我认为这没关系,因为我实际上不是在创建文件,只是在修改它。如果文件不存在,或者存在时没有所需的字符串,这将起作用。

是的,那么前提条件怎么可能是函数而不是另一个文件呢?它不能。制作