我有以下命令行,它可以在Linux命令提示符下运行:
vi /tmp/test.txt -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )
它创建一个临时文件(使用Process Substitution),其中包含以下vim
命令:
:1 s/^\/\/ VERSION: .*$/\/\/ VERSION: $(date)/g
它打开文件/tmp/test.txt
进行编辑,并从先前创建的临时文件中执行命令。它找到第1行并用当前时间戳替换该行。看起来有点像这样:
// VERSION: Fri Apr 12 21:20:03 CEST 2013
...
...
接下来我可以进行任何必要的编辑,只有当我决定保存文件时,所有更改都会提交到磁盘。首先更改磁盘上的文件,然后启动编辑器不是一个选项,因为文件将具有不同的时间戳,而内容本身不会更改。
到目前为止,它按设计/预期工作。
现在我正在尝试将此vi命令行移动到make文件中,这就是我失败的地方。我尝试了$(shell .....)
构造,但是make会给我带来错误。
edit:
$(shell vi $(src).cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )
我正在试图弄清楚Makefile中的行应如何阅读摆弄额外的引号和括号,但我还没有解决它。
我正在运行Ubuntu Linux 12.10和GNU Make 3.81
vi project.cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )
Make似乎不喜欢“Process Substitution”构造<( command )
。我不想使用额外的(真实)文件。
€ make edit
vi project.cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )
/bin/sh: 1: Syntax error: "(" unexpected
make: *** [edit] Error 2
答案 0 :(得分:9)
在制作配方中使用$(shell ...)
几乎从不正确。你已经在shell中...只需直接输入你想要的命令。尝试使用make $(shell ...)
函数只会增加混乱。您必须通过撰写$
来逃避$$
。
您还有另一个问题:make
始终使用/bin/sh
调用其脚本,并且您使用的是特定于bash的构造(<(...)
)。
当然,更大的问题是为什么你使用vi(一个可视化编辑器)来做这样的自动更改,而不是例如为它设计的sed
。我将其重写为:
edit:
sed -i "1 s,^// VERSION: .*,// VERSION: $$(date)," $(src).cpp
如果您真的想使用vi,则必须执行以下操作:
SHELL := /bin/bash
edit:
vi '$(src).cpp' -s <( echo ":1 s/^\/\/ VERSION: .*$$/\/\/VERSION: $$(date)/g" )