Syntax error near unexpected token 'fi'
BashBash Problem Overview
I'm trying to write a script that removes all the .jpg's that end in an odd number. This is my code:
#!/bin/bash
echo "start\n"
for f in *.jpg
do
fname=$(basename "$f")
echo "fname is $fname\n"
fname="${filename%.*}"
echo "fname is $fname\n"
if[$((fname % 2)) -eq 1 ] then
echo "removing $fname\n"
rm $f
fi
done
When I run it it outputs start and then says "syntax error near unexpected token 'fi'"
When I had then on the line after if it said "syntax error near unexpected token 'then'"
How do i fix this?
Bash Solutions
Solution 1 - Bash
As well as having then
on a new line, you also need a space before and after the [
, which is a special symbol in BASH.
#!/bin/bash
echo "start\n"
for f in *.jpg
do
fname=$(basename "$f")
echo "fname is $fname\n"
fname="${filename%.*}"
echo "fname is $fname\n"
if [ $((fname % 2)) -eq 1 ]
then
echo "removing $fname\n"
rm "$f"
fi
done
Solution 2 - Bash
Use Notepad ++ and use the option to Convert the file to UNIX format. That should solve this problem.
Solution 3 - Bash
"Then" is a command in bash, thus it needs a ";" or a newline before it.
#!/bin/bash
echo "start\n"
for f in *.jpg
do
fname=$(basename "$f")
echo "fname is $fname\n"
fname="${filename%.*}"
echo "fname is $fname\n"
if [$[fname%2] -eq 1 ]
then
echo "removing $fname\n"
rm $f
fi
done
Solution 4 - Bash
The first problem with your script is that you have to put a space after the [
.
Type type [
to see what is really happening. It should tell you that [
is an alias to test
command, so [ ]
in bash is not some special syntax for conditionals, it is just a command on its own. What you should prefer in bash is [[ ]]
. This common pitfall is greatly explained here and here.
Another problem is that you didn't quote "$f"
which might become a problem later. This is explained here
You can use arithmetic expressions in if
, so you don't have to use [ ]
or [[ ]]
at all in some cases. More info here
Also there's no need to use \n
in every echo
, because echo
places newlines by default. If you want TWO newlines to appear, then use echo -e 'start\n'
or echo $'start\n'
. This $''
syntax is explained here
To make it completely perfect you should place --
before arbitrary filenames, otherwise rm
might treat it as a parameter if the file name starts with dashes. This is explained here.
So here's your script:
#!/bin/bash
echo "start"
for f in *.jpg
do
fname="${f##*/}"
echo "fname is $fname"
if (( fname % 2 == 1 )); then
echo "removing $fname"
rm -- "$f"
fi
done
Solution 5 - Bash
@sagar's answer solved my problem (Save file to UNIX format), please note that if you are using VSCode, you can select the file's end of line sequence (LF or CRLF) at the bottom right.
Also see this CRLF vs LF if you would like to understand the why. Common problem when you are working on different OS.