bash : Illegal number - bash

When I run this bash script :
if [ [$EUID -ne 0] ]; then
echo "This script must be run as root" 1>&2
exit 1
else
printf " whathever "
exit 0
fi
I have this error :
./myScript: 15: [: Illegal number: [
Do you see any problem ?

You have syntax error in your if condition, use this if condition:
if [ "$EUID" -ne 0 ];
OR using [[ and ]]
if [[ "$EUID" -ne 0 ]];

You have syntax error in your if condition, use this if condition:
if [ "$EUID" -ne 0 ];
OR using [[ and ]]
if [[ "$EUID" -ne 0 ]];
If you use the KSH88+/Bash 3+ internal instruction [[, it's not necessary to use doubles quotes around the variables operands :
[ ~/test]$ [[ $var2 = "string with spaces" ]] && echo "OK" || echo "KO"
OK
Instead of the external command test or his fork [ :
[ ~/test]$ [ $var2 = "string with spaces" ] && echo "OK" || echo "KO"
bash: [: too many arguments
KO
[ ~/test]$ [ "$var2" = "string with spaces" ] && echo "OK" || echo "KO"
OK
Of course, you also have to choose the operators according to the type of operands :
[ ~/test]$ var1="01"
[ ~/test]$ [ "$var1" = "1" ] && echo "OK" || echo "KO"
KO
[ ~/test]$ [ "$var1" -eq "1" ] && echo "OK" || echo "KO"
OK

two suggestions apart from what everyone else has pointed out already.
rather than doing else [bunch of code because we are root] fi, just replace the else with fi. once you've tested for the failure condition you are concerned about and taken appropriate action, no need to continue to be within the body of the conditional.
$EUID is a bashism, if you would like to make this portable to shells such as ksh, replacing it with:
if [ $(id -u) -ne 0 ]; then echo "ur not root bro"; exit 1; fi
would be a good way to do it.

using
sudo bash shell_script.sh
instead of
sudo sh shell_script.sh
solved in my case.

Related

Bash Command Nested conditional statements failing, but why

I have a bash script that runs many conditional statements, but when I run the script, it only hits the following line: if [ $? -eq 0 ]
touch /tmp/converted.json
tool test --json --all-projects | tee >> /tmp/converted.json
ret=$?
set -o pipefail
#no vulns
if ((ret == 0)); then
echo "Hooray!"
#found vulns
elif ((ret == 1)); then
then
#check single project
if [[ $firstchar == "{" ]]
then
echo "SINGLE PROJECT"
elif [[ $firstchar == "[" ]]
then
echo "MULTIPROJECT"
else
echo "didnt get a single or multiproject"
fi
#error with your command
elif ((ret == 2)); then
then
echo "An error occurred"
#no manifest
elif ((ret == 3)); then
then
echo "Ensure your repo has a proper required manifest file"
else
echo "Something else occurred"
fi
Thus, why does this continue to hit if((ret==0)) condition?
Thanks
$? has the exit status of the last command executed. The last command at elif [ $? -eq 1 ] was [ executed at if [ $? -eq 0 ].
if [ $? -eq 0 ] # executes `[`
then
: dont care
elif [ $? -eq 1 ] # $? here has a nonzero the exit status of `[`
Just save the exit status to a variable before calling any command right after executing the command you are interested in. In bash you may use arithmetic expansion ((...)).
some_command
ret=$?
if ((ret == 0)); then
: dont care
elif ((ret == 1)); then

Bash detect 1st input parameter is "debug"?

I want to detect if the 1st bash input parameter is "debug"(string).
I write script like this:
#! /usr/bin/env bash
if [ "$#" -eq "1" && "$1" -eq "debug" ]; then
echo "hello debug"
fi
Error message:
line 3: [: missing `]'
I don't know why, please help.
Compare strings with ==, -eq is an arithmetic operator. Also, within [] you have to use the -a operator instead of &&, or split it in two. Here are a few different ways to write the same thing:
if [[ $# -eq 1 && "$1" == "debug" ]] ; then
echo "hello debug"
fi
if [[ "$#" == "1" && "$1" == "debug" ]] ; then
echo "hello debug"
fi
if [ "$#" == "1" ] && [ "$1" == "debug" ] ; then
echo "hello debug"
fi
if [ "$#" == "1" -a "$1" == "debug" ] ; then
echo "hello debug"
fi
Instead of [ "$#" -eq "1" && "$1" -eq "debug" ], use either [ "$#" -eq "1" ] && [ "$1" -eq "debug" ] or [ "$#" -eq "1" -a "$1" -eq "debug" ]. The problem is that && is bash's way of saying "and", rather than -a, which is test's way of saying "and". You can't use a bash "and" inside of test.

"[:too many arguments" error in BASH

I'm learning BASH through HackerRank.There's an exercise in which the lengths of the triangle is given and then you need to find whether the triangle is isosceles,scalene or equilateral.I wrote the following code:
read a
read b
read c
if [ [ "$a" -eq "$b" ] && [ "$b" -eq "$c" ] ]
then
echo "EQUILATERAL"
elif [ [ "$a" -eq "$b" ] || [ "$b" -eq "$c" ] ]
then
echo "ISOSCELES"
else
echo "SCALENE"
fi
But then I get the following error
solution.sh: line 4: [: too many arguments
solution.sh: line 7: [: too many arguments
solution.sh: line 7: [: too many arguments
Why is this happening? I tried long and hard to rectify it but nothing worked out
You can combine conditions either ommiting the surrounding brackets like this
if [ "$a" -eq "$b" ] && [ "$b" -eq "$c" ]
or by combining the conditions with -a/-o like this
if [ "$a" -eq "$b" -a "$b" -eq "$c" ]
see http://wiki.bash-hackers.org/commands/classictest#and_and_or
&& and || are Bash list operators. In a chain of commands, the next command is executed only if the previous command returned 0 (&&) or nonzero (||).
[ is an alias for the Bash internal test command and has arguments such as -eq or -ne. ] ends its command line. Type help test for more information.
So if you write a conditional expression, you do not put the list operators inside brackets.
Try, for example, this instead of the respective line in your code:
if [ "$a" -eq "$b" ] && [ "$b" -eq "$c" ]
then
[ isn't a grouping operator in bash, you can't use it to group tests.
there are a number of different ways to express the tests you want to make, numeric evaluation mode is probably easiest to read
if (( a == b && b == c ))
if (( a == b || b == c || c == a ))
This is going to break if you have decimal fractions, but will work fine for integers.
[ is a conditional command, like an alias for sh's test built-in command.
[[ is the same for bash which has more test options.
So make a choice between [ and [[ but not [ [ which means two command.
Example:
# [ [ -n 'test' ] ]
bash: [: too many arguments
# [ -n 'test' ] && echo $?
0
# [[ -n 'test' ]] && echo $?
0

Error executing shell script

I am trying to execute the following shell script
#!/bin/sh
echo "start"
if [ $# != 2 || $1 != "first" || $1 != "second" ]
then
echo "Error"
fi
echo "done"
and I'm getting the following output:
start
./autobuild.sh: line 3: [: missing `]'
./autobuild.sh: line 3: !=: command not found
./autobuild.sh: line 3: !=: command not found
done
I have no idea how to resolve the errors. Even if I use -ne instead of !=, I get the same errors. Please help.
Your syntax is incorrect. If you want multiple conditions in an if statement you need to have multiple [] blocks. Try:
if [ $# != 2 ] || [ $1 != "first" ] || [ $1 != "second" ]
But, it's better to use [[ (if your shell supports it) as it is safer to use. I would go for:
if [[ $# -ne 2 || $1 != "first" || $1 != "second" ]]
See this question on brackets: Is [[ ]] preferable over [ ] in bash scripts?
While OR ing the conditions should be seperate as follows :
#!/bin/sh
echo "start"
if [ $# != 2] || [ $1 != "first" ] || [ $1 != "second" ]
then
echo "Error"
fi
echo "done"
Try substituting -NE for !=.
if-usage samples
This should work:
#!/bin/sh
echo "start"
if [ $# -ne 2 -o $1 -ne "first" -o $1 -ne "second" ]
then
echo "Error"
fi
echo "done"

Bash if statement with multiple conditions throws an error

I'm trying to write a script that will check two error flags, and in case one flag (or both) are changed it'll echo-- error happened. My script:
my_error_flag=0
my_error_flag_o=0
do something.....
if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" && "$my_error_flag_o"="2" ]]; then
echo "$my_error_flag"
else
echo "no flag"
fi
Basically, it should be, something along:
if ((a=1 or b=2) or (a=1 and b=2))
then
display error
else
no error
fi
The error I get is:
line 26: conditional binary operator expected
line 26: syntax error near `]'
line 26: `if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" && "$my_error_flag_o"="2" ]]; then'
Are my brackets messed up?
Use -a (for and) and -o (for or) operations.
tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html
Update
Actually you could still use && and || with the -eq operation. So your script would be like this:
my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] || [ $my_error_flag_o -eq 2 ] || ([ $my_error_flag -eq 1 ] && [ $my_error_flag_o -eq 2 ]); then
echo "$my_error_flag"
else
echo "no flag"
fi
Although in your case you can discard the last two expressions and just stick with one or operation like this:
my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] || [ $my_error_flag_o -eq 2 ]; then
echo "$my_error_flag"
else
echo "no flag"
fi
You can use either [[ or (( keyword. When you use [[ keyword, you have to use string operators such as -eq, -lt. I think, (( is most preferred for arithmetic, because you can directly use operators such as ==, < and >.
Using [[ operator
a=$1
b=$2
if [[ a -eq 1 || b -eq 2 ]] || [[ a -eq 3 && b -eq 4 ]]
then
echo "Error"
else
echo "No Error"
fi
Using (( operator
a=$1
b=$2
if (( a == 1 || b == 2 )) || (( a == 3 && b == 4 ))
then
echo "Error"
else
echo "No Error"
fi
Do not use -a or -o operators Since it is not Portable.
Please try following
if ([ $dateR -ge 234 ] && [ $dateR -lt 238 ]) || ([ $dateR -ge 834 ] && [ $dateR -lt 838 ]) || ([ $dateR -ge 1434 ] && [ $dateR -lt 1438 ]) || ([ $dateR -ge 2034 ] && [ $dateR -lt 2038 ]) ;
then
echo "WORKING"
else
echo "Out of range!"
You can get some inspiration by reading an entrypoint.sh script written by the contributors from MySQL that checks whether the specified variables were set.
As the script shows, you can pipe them with -a, e.g.:
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
...
fi

Resources