Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute complex shell command from makefile

I have the following command line that works from the Linux command prompt:

vi /tmp/test.txt -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )

It creates a temporary file (using Process Substitution) that contains the following vim command:

:1 s/^\/\/ VERSION: .*$/\/\/ VERSION: $(date)/g

It opens file /tmp/test.txt for editing and executes the command from the previously created temporary file. It finds line 1 and replaces the line with a current time stamp. It looks a bit like this:

// VERSION: Fri Apr 12 21:20:03 CEST 2013
...
...

Next I can do any required editing and only when I decide to save the file, all changes are commited to disk. It is not an option to first change the file on disk, then start the editor, as the file will have a different timestamp while the contents itself didn't change.

So far it works as designed / intended.

Now I'm trying to move this vi command line into a make file and that is where I fail. I tried a $(shell .....) construction, but make is throwing errors at me.

edit:
        $(shell vi $(src).cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )

I'm trying to figure out how the line in the Makefile should read fiddling with extra quotes and parentheses, but I haven't solved it yet.

I am running Ubuntu Linux 12.10 and GNU Make 3.81

vi project.cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )

Make doesn't seem to like the "Process Substitution" construction <( command ). I do not want to use an extra (real) file.

€ make edit
vi project.cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )
/bin/sh: 1: Syntax error: "(" unexpected
make: *** [edit] Error 2
like image 918
jippie Avatar asked Feb 05 '26 21:02

jippie


1 Answers

Using $(shell ...) inside of a make recipe is virtually never correct. You're already in a shell... just type the commands you want directly. Trying to use the make $(shell ...) function just adds confusion. You will have to escape $ by writing $$.

You have another problem: make always invokes its scripts using /bin/sh and you're using a bash-specific construct (<(...)).

Of course, the bigger question is why you're using vi, which is a visual editor, to do automated changes like this instead of, for example, sed which is designed for it. I'd rewrite it as something like:

edit:
        sed -i "1 s,^// VERSION: .*,// VERSION: $$(date)," $(src).cpp

If you really want to use vi, you'll have to do something like:

SHELL := /bin/bash

edit:
        vi '$(src).cpp' -s <( echo ":1 s/^\/\/ VERSION: .*$$/\/\/VERSION: $$(date)/g" )
like image 130
MadScientist Avatar answered Feb 08 '26 14:02

MadScientist