Syntax error near unexpected token 'else' - bash

I have looked at this for about 30 minutes now and can't seem to find the error in this. It happens at my if/else block at the end.
default()
{
for file in /*
do
if [ -f $file ]; then
((filecount++))
elif [ -d $file ]; then
((dircount++))
fi
done
echo The number of files is "$filecount"
echo The number of directories is "$dircount"
}
specific()
{
for file in $param
do
if [ -f $file ]; then
((filecount++))
elif [ -d $file ]; then
((dircount++))
fi
done
echo The number of files is "$filecount"
echo The number of directories is "$dircount"
}
#Variables
declare -a param=$1
declare -i filecount="0"
declare -i dircount="0"
#Action
if [ $param=='-h' ]; then
echo To use this program, enter a directory path after $0 or leave it blank to use current directory.
elif [ $param=='' ]; then
default()
else
specific()
fi
exit 0
Here is the error code. Any help is appreciated.
./countf.sh: line 44: syntax error near unexpected token `else'
./countf.sh: line 44: `else'

I checked your syntax only and found these errors.
function calls. As #Etan Reisner mentioned.
You need spaces around the comparison operator. like [ $param == '-h' ];
you need to double quote your variable. use [ "$param" == '-h' ] instead of [ $param == '-h' ] . Check this for more details. Double quote to prevent globbing and word splitting
I suggest you to test your script here. http://www.shellcheck.net/ I also should do that first instead of manually check your script.

Related

Bash unexpected token near 'then'

I have a syntax error, more like a unexpected symbol near a token 'then', but I can't figure it out..
#!/bin/bash
function Functie(){
LINE=1
while read -r CURRENT_LINE; do
CONTOR=1
for word in "$CURRENT_LINE"; do
if[ "$word" == "$2" ];
then
CONTOR=$CONTOR+1
fi
done
if [ "$CONTOR" -eq "$3" ];
then
echo "$CURRENT_LINE"
fi
LINE=$LINE+1
done < "./"$1""
}
Functie "File1.txt" "Ana" "2"
Run your code through ShellCheck to catch several syntax errors.
Correcting them yields:
#!/bin/bash
function Functie(){
LINE=1
while read -r CURRENT_LINE; do
CONTOR=1
for word in $CURRENT_LINE; do
if [ "$word" == "$2" ];
then
CONTOR=$CONTOR+1
fi
done
if [ "$CONTOR" -eq "$3" ];
then
echo "$CURRENT_LINE"
fi
LINE=$LINE+1
done < ./"$1"
}
Functie "File1.txt" "Ana" "2"
One issue it doesn't detect is the bad assignments. To increment a variable write one of these:
CONTOR=$(($CONTOR+1))
CONTOR=$((CONTOR+1))
((CONTOR += 1))
((++CONTOR))

BASH file test operators with empty strings

What do the BASH file test operators return when the path argument is an empty string? For example:
directory=""
# Something may or may not set "directory"
if [ -d "$directory" ]; then
# Do something...
fi
You need to quote $directory:
if [ -d "$directory" ]; then
Otherwise, after expansion you are left with the equivalent of
if [ -d ]; then
which is equivalent to if [ -n "-d" ]; then, and so is always true. (-d is a non-empty string.)
In your example, the statement will yield the following test:
if [ -d ]; then
...
fi
Which will not test what you wish to.
What is the accepted practice to prevent such error is to encase the variable in double quotes like this:
if [ -d "$directory" ]; then
...
fi

Passing Argument in bash

I am having trouble to find the syntax error in the following script.
bash test.sh cat
#!/bin/bash
if [ $1 = "cat" ]; then
echo "valid"
else
echo "invalid"
fi
If you are not giving arguments, $1 will evaluate to a blank space and you are probably seeing line 2: [: =: unary operator expected. To fix, add quotes around $1:
#!/bin/bash
if [ "$1" = "cat" ]; then
echo "valid"
else
echo "invalid"
fi
This way, if you don't call with an argument it will still compare to an empty string.
In general, you should always put quotes around your variable expansions, otherwise you may see unexpected errors if the variable is empty (as you just saw) or if the variable has a space in it.
The arg $1 has no value. You could do something like this.
if [ -z $1 ]
then
echo "you forgot to give me an arg."
exit 1
fi
if [ $1 = "cat" ]; then
echo "valid"
else
echo "invalid"
fi
you can also do:
if [ $# -ne 1 ]; then
echo "Usage: ./script.sh <arg1>"
exit 1
fi

if, elif, else statement issues in Bash

I can't seem to work out what the issue with the following if statement is in regards to the elif and then. Keep in mind the printf is still under development I just haven't been able to test it yet in the statement so is more than likely wrong.
The error I'm getting is:
./timezone_string.sh: line 14: syntax error near unexpected token `then'
./timezone_string.sh: line 14: `then'
And the statement is like so.
if [ "$seconds" -eq 0 ];then
$timezone_string="Z"
elif[ "$seconds" -gt 0 ]
then
$timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
else
echo "Unknown parameter"
fi
There is a space missing between elif and [:
elif[ "$seconds" -gt 0 ]
should be
elif [ "$seconds" -gt 0 ]
All together, the syntax to follow is:
if [ conditions ]; then
# Things
elif [ other_conditions ]; then
# Other things
else
# In case none of the above occurs
fi
As I see this question is getting a lot of views, it is important to indicate that the syntax to follow is:
if [ conditions ]
# ^ ^ ^
meaning that spaces are needed around the brackets. Otherwise, it won't work. This is because [ itself is a command.
The reason why you are not seeing something like elif[: command not found (or similar) is that after seeing if and then, the shell is looking for either elif, else, or fi. However it finds another then (after the mis-formatted elif[). Only after having parsed the statement it would be executed (and an error message like elif[: command not found would be output).
You have some syntax issues with your script. Here is a fixed version:
#!/bin/bash
if [ "$seconds" -eq 0 ]; then
timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
echo "Unknown parameter"
fi
[ is a command (or a builtin in some shells). It must be separated by whitespace from the preceding statement:
elif [
I would recommend you having a look at the basics of conditioning in bash.
The symbol "[" is a command and must have a whitespace prior to it. If you don't give whitespace after your elif, the system interprets elif[ as a a particular command which is definitely not what you'd want at this time.
Usage:
elif(A COMPULSORY WHITESPACE WITHOUT PARENTHESIS)[(A WHITE SPACE WITHOUT PARENTHESIS)conditions(A WHITESPACE WITHOUT PARENTHESIS)]
In short, edit your code segment to:
elif [ "$seconds" -gt 0 ]
You'd be fine with no compilation errors. Your final code segment should look like this:
#!/bin/sh
if [ "$seconds" -eq 0 ];then
$timezone_string="Z"
elif [ "$seconds" -gt 0 ]
then
$timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
else
echo "Unknown parameter"
fi
Missing space between elif and [ rest your program is correct. you need to correct it an check it out. here is fixed program:
#!/bin/bash
if [ "$seconds" -eq 0 ]; then
timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
echo "Unknown parameter"
fi
useful link related to this bash if else statement

shell: return values of test on file/directory

I'm not able to check the return values of the function test; man test didn't help me much.
#!/bin/bash
test=$(test -d $1)
if [ $test -eq 1 ]
then
echo "the file exists and is a directory"
elif [ $test -eq 0 ]
echo "file does not exist or is not a directory"
else
echo "error"
fi
Try, instead
if test -d $1
then
echo 'the file exists and is a directory'
else
echo 'the file doesn't exist or is not a directory'
fi
Every time you use test on the return code of test, God kills a kitten.
if test -d "$1"
or
if [ -d "$1" ]
$(test -d $1) is going to be substituted with what test outputs, not its return code. If you want to check its return code, use $?, e.g.
test -d $1
test=$?
if [ $test -eq 1 ]
...

Resources