I have an annoying problem, I want a script to search through a makefile (using grep) for a particular annoying line. The problem is best illustrated concretely:

someMakefile (minimal Makefile):

#!/usr/bin/env bash
echo bla bla
cp $(OBJ_DIR)/$(EXE_FILE) ../bin/.
echo 'doing something else now'

testScript.sh (test for the existence of the difficult line):

cat testScript.sh

#!/usr/bin/env bash
set -x
foundNumLines = $(grep -in 'cp $(OBJ_DIR)/$(EXE_FILE) ../bin/.' someMakefile)
echo "foundNumLines = $foundNumLines"
set +x

From the commandline (this DOES work):

$ grep -in 'cp $(OBJ_DIR)/$(EXE_FILE) ../bin/.' someMakefile
5:cp $(OBJ_DIR)/$(EXE_FILE) ../bin/.

From the script (this does NOT work and I cannot figure out how to make it work):

$ ./testScript.sh 
++ grep -in 'cp $(OBJ_DIR)/$(EXE_FILE) ../bin/.' someMakefile
+ foundNumLines = 5:cp '$(OBJ_DIR)/$(EXE_FILE)' ../bin/.
./testScript.sh: line 4: foundNumLines: command not found
+ echo 'foundNumLines = '
foundNumLines = 
+ set +x

When "grep" works from the script, I wanted to use maybe "wc" or similar, to detect the presence of the line and then do something, based on this...

I just cannot make it work, tried many combinations of "'" \' etc - I hope you understand, what I'm trying to achieve, please help with ideas/suggestions, thanks!


To assign values to variables, you need var=value and not var = value. Spaces are significant in this context and that's why you get the command not found error from this line:

foundNumLines = $(grep -in 'cp $(OBJ_DIR)/$(EXE_FILE) ../bin/.' someMakefile)

That isn't a variable assignment, it is three commands: foundNumLines, =, and $(grep ... ). What you need is:

foundNumLines=$(grep -in 'cp $(OBJ_DIR)/$(EXE_FILE) ../bin/.' someMakefile)

I know you said it was a makefile, but I should point out that the $() construct has meaning in the shell as well. $(foo) will run the command foo and return its output. Therefore, this line:

cp $(OBJ_DIR)/$(EXE_FILE) ../bin/.

Will first try to execute $OBJ_DIR and $EXE_FILE as commands and insert their output in the place of the variables. Since OBJ_DIR will presumably not be a command, this means that you will be executing

cp / ../bin/.

Or, if EXE_FILE is in your path and executable:

cp /$outputOfExec_File ../bin/.

(by the way, there's no need for . there, ../bin/ is the same as ../bin/.).

I thought I'd mention this since you have a bash shebang at the top of your makefile example, so I am assuming you are executing it as a shell script.

  • Oh, stupid me... So, basically I think the major issue was that I've been programmed in other languages lately and just entirely forget to remove the space around the equal-sign (var=value and not var = value). For the reference it's great that you added a detailed explanation (about the OBJ_DIR being empty here etc, I know - I just wanted to include a minimal example and therefore it's empty here), if other people see it, it might be helpful, so I've upvoted and marked as answered. Thanks! – Okay Dokey May 8 '19 at 8:21
  • 1
    @OkayDokey yeah, I know the feeling. It takes some getting used to. :) – terdon May 8 '19 at 8:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.