bash shell script, searching for complex line in makefile (shell parameter expansion issue)
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
OBJ_DIR='something'
EXE_FILE='my_exe'
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 +xFrom 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 +xWhen "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!
01 Answer
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.
2More in general
"Zoraya ter Beek, age 29, just died by assisted suicide in the Netherlands. She was physically healthy, but psychologically depressed. It's an abomination that an entire society would actively facilitate, even encourage, someone ending their own life because they had no hope. Th…"