Word Unexpected (expecting ")") with Makefile - bash

I'm making a makefile and I'm working on a target with no dependencies that checks to see if a file named README exists in the current directory and if it does, read it using less or else exit quitely: give no errors whatsoever--the command to run the target should print nothing to console if this is the case.
I've tried a couple different ways but nothing really seems to work (PAGER is simply a var equal to less):
read :
ifneq ("$(wildcard README)","")
-#$(PAGER) README
endif
And also with this code
read :
-#for file in *;\
do \
if [ ${file} == "README" ]; then\
$(PAGER) "README" ;\
fi;\
done
With the first chunk I keep getting an error akin to /bin/sh: Syntax error: word unexpected (expecting ")") and for the life of me I just don't get what it's saying. I certainly don't think there's a syntax error, perhaps I'm misusing make.
For the latter code I get an unexpected operator error for the ==.
I've also tried simpler things like these two single liner solutions but get similar errors:
-#test -a README && less README
-#[ -a README ] && less README
Any help would be greatly appreciated.
EDIT: I was digging further and saw something promising and explicitly setting my shell to /bin/bash (SHELL := /bin/bash) yet no dice.

read:
#if [ -e README ]; then less README; fi

You should try to extract your shell code in separate *.sh files so that you can specify them as commands in your makefile (and make sure that the *.sh files are executable).

Related

makefile bash recipe - include file if exists at recipe time

I have a makefile that runs some custom tools. One of those tools sometimes spits out an extra file. That file must be used in a subsequent recipe (if it exists). I can't assume it exists in the dependencies, but I must use add it to the subsequent recipe command if it is there. Here's how I currently handle it:
final_recipe:
[ ! -f "maybe.file" ] || tool maybe.file ...
[ -f "maybe.file" ] || tool ...
This is ugly. Any suggestions for a bash executable line where bash can evaluate whether the file exists and embed it if it does? Something more like:
final_recipe
tool ([ -f "maybe.file"] ? maybe.file) ...
This may achieve what you wanted :
final_recipe:
tool $$(test -f maybe.file && echo maybe.file) ...
Updated upon MadScientist's comment

How do I resolve Syntax error 'for' is not matched?

I have little scripting experience. I have tried a new script to loop through multiple subdirectories and edit a file if the subdirectory exists. Here is the code I've failed with after multiple attempts, but I cannot resolve the for loop error:
!#/usr/din/sh
for domain in {PGBWAHS_NA PGBWAHS04_NA PGBWAHD_NA PGBWAHD04_NA PGBWAHQ_NA PGBWAHQ02_NA PGBWAHQ03_NA PGBWAHQ04_NA PGBWAHP_NA PGBWAHP02_NA PGBWAHP03_NA PGBWAHP04_NA
do
echo "$domain this is the current domain from the array"
cd /opt/tibco/tra/domain/$domain
echo `pwd` "this is the directory after cd command"
cp hawkagent.cfg hawkagent.cfg.back
sed 's/-scan_rate 10/-scan_rate 30/' hawkagent.cfg
Done
____________________
Error message returned:
$ ./modify_log_scan_rate.sh
./modify_log_scan_rate.sh[3]: Syntax error at line 3 : `for' is not matched.
Remove the opening curly braces after in: for domain in *{*PGBWAHS_NA ...
Done needs to be done (case matters).
– Etan Reisner

parameter expansion syntax bash

I am trying to write a short script that will take two command line parameters as file extensions and change all files with the first extension to have the second extension. I am pretty sure the following script should work but for some reason it gives me a syntax error on the line where the variable name is defined and I am not sure why. I am rather new to bash scripting so any help would be greatly appreciated!
for f in "*$1" do
name=${f%.*}
mv $f "$name$2"
done
The error message printed by Bash looks like:
./script: line 4: syntax error near unexpected token `name=${f%.*}'
./script: line 4: `name=${f%.*}'
The reason is that you are missing a ; or newline before do. Also you don't want to quote * in "*$1", since the * will be taken as a literal. Corrected script:
#!/usr/bin/env bash
for f in *"$1"; do
name=${f%.*}
mv "$f" "$name$2"
done

Error in BASH shell script - Using Variables as References

Two questions about problems I'm having writing up a BASH script that uses variables. I cannot for the life of me figure this out and it is KILLING me.
1) I have the following code.
pdir=/media/The_Enforcer/ICA_Doug/Participants/RS1
cd ${pdir}
for subject in * ; do
subdir=${pdir}/${subject} ;
cd ${subdir} ;
subj= echo ${subject} | head -c-9
3dAFNItoNIFTI -prefix ICA/cleanRS_NII_${subj} RSFC_LFF_rall_${subj}+orig ;
cd ${pdir} ;
done
${subject} is a subject ID which is ########.results. For example: 1R101U1A.results. Basically my code cd's me into that directory in which is a file called RSFC_LFF_rall_1R101U1A+orig which I want to process via the code line that starts with 3dAFNItoNIFTI. Obviously I can't use ${subject} variable in that code line because it would attempt to find the file RSFC_LFF_rall_1R101U1A.results+orig which does not exist. So to fix this I made a new variable called ${subj} which, via the echo pipeline, basically cuts off the last 9 letters of ${subject} which, in effect, removes the .results. When I do this and echo ${subj} it gives me 1R101U1A which is exactly what I want.
However, the line of code that starts with 3dAFNItoNIFTI errors with the following:
FATAL ERROR: Can't open dataset 'RSFC_LFF_rall_+orig'
I have tried declaring the ${subj} variable like, five different ways (including using head, tail, cut, and colons) and I still get this error.
What am I doing wrong?
2) In attempting to define ${subj} in numerous ways I also tried this method:
${subj}= ${subject:0:8}
When I did this, the final bracket refused to close - i.e. the closing bracket did not turn the color of the opening bracket and when I attempted to run the script I got an error at that line saying 'command not found.' I checked my syntax against the examples I was following and it looks fine? Am I missing something here?
Try this:
cd "/media/The_Enforcer/ICA_Doug/Participants/RS1"
for subject in * ; do
cd $subject
subj=${subject%.results}
3dAFNItoNIFTI -prefix ICA/cleanRS_NII_${subj} RSFC_LFF_rall_${subj}+orig
cd ..
done
${subject%.results} removes .results from the end of the string.
See Shell-Parameter-Expansion.

Error: =: command not found (Bash Script)

I found a nifty little shell script that I wanted to use from this website here. I have followed everything step-by-step, but receive the following error when running this on my CentOS box.
./deploy: line 3: =: command not found
Line 3 only contains...
$ERRORSTRING = "Error. Please make sure you've indicated correct parameters"
I've tried toying around with a bit, but don't understand why it won't accept the "=" character. Is there something wrong with the script, or is it merely something different in the way that my server processes the script?
Thanks!
Gah, that script is full of bad scripting practices (in addition to the outright error you're running into). Here's the outright error:
$ERRORSTRING = "Error. Please make sure you've indicated correct parameters"
As devnull pointed out, this should be:
ERRORSTRING="Error. Please make sure you've indicated correct parameters"
A couple of lines down (and again near the end), we have:
echo $ERRORSTRING;
...which works, but contains two bad ideas: a variable reference without double-quotes around it (which will sometimes be parsed in unexpected ways), and a semicolon at the end of the line (which is a sign that someone is trying to write C or Java or something in a shell script). Use this instead:
echo "$ERRORSTRING"
The next line is:
elif [ $1 == "live" ]
...which might work, depending on whether the value of $1 has spaces, or is defined-but-blank, or anything like that (again, use double-quotes to prevent misparsing!). Also, the == comparison operator is nonstandard -- it'll work, because bash supports it in its [ ... ] builtin syntax, but if you're counting on having bash extensions available, why not use the much cleaner [[ ... ]] replacement? Any of these would be a better replacement for that line:
elif [ "$1" = "live" ]
elif [[ $1 == "live" ]]
elif [[ "$1" == "live" ]]
Personally, I prefer the last. The double-quotes aren't needed in this particular case, but IMO it's safest to just double-quote all variable references unless there's a specific reason not to. A bit further down, there's a elif [ $2 == "go" ] that the same comments apply to.
BTW, there's a good sanity-checking tool for shell scripts at www.shellcheck.net. It's not quite as picky as I am (e.g. it doesn't flag semicolons at the ends of lines), but it pointed out all of the actual errors in this script...
"Devnulls" answer was correct -- I had to remove the spaces around the "=" and remove the "$" from that line as well. The end result was...
ERRORSTRING="Error. Please make sure you've indicated correct parameters"
I've upvoted Devnull and gniourf_gniourf's comments.
Thank you to all whom have assisted!

Resources