"if[ 0 -lt 1] command not found" error in shell script [duplicate] - linux

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Why is whitespace sometimes needed around metacharacters?
(5 answers)
Closed 5 years ago.
I got error message as if[ 0 -lt 1] command not found. I just started shell scripting. I don't know what's wrong in my code:
if[ $# -lt 1 ]
then
echo "Give a number as a parameter. Try again."
else
n=$1
sum= 0
sd=0
while[ $n -gt 0 ]
do
sd=`expr $n % 10`
sum=`expr $sum + $sd`
n=`expr $n / 10`
done
echo "Sum of digits for $1 is $sum"

You need a space between if and [. You'll have the same issue after while.
The [ ] notation is kind of an oddity in shell. It looks like part of the language, but it actually isn't. The if and while words always need to be followed by whitespace and then a command, which is executed, and considered to be true or false according to whether its exit code is zero or nonzero.
So there is actually a command named [ which evaluates the conditions given on its command line, and terminates with an exit code according to whether the condition evaluated true or false. You can see an executable in the /usr/bin directory on most systems (though the shell usually has a built-in version for efficiency). It works the same as test.
Also, keep in mind that if needs a matching fi after the else clause.

Check out https://www.shellcheck.net/ (Open Source - free)
It allows you to check your shell scripts before running them. You just copy your shell script into the browser and do a syntax check, you can also run locally.
Why?
Well, this I think will really help you learn what you are doing wrong.
i.e. Fix spacing errors etc.
Example Output:
$ shellcheck myscript
Line 1:
if[ $# -lt 1 ]
^-- SC1046: Couldn't find 'fi' for this 'if'.
^-- SC1073: Couldn't parse this if expression.
^-- SC1069: You need a space before the [.
Line 8:
while[ $n -gt 0 ]
^-- SC1069: You need a space before the [.
Line 15:
^-- SC1047: Expected 'fi' matching previously mentioned 'if'.
^-- SC1072: Expected 'fi'. Fix any mentioned problems and try again.
$

Related

Nothing happens on bourne shell script [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I coded code that print decimals in 1 to 100.
and I executed this code, but Nothing happens...
I want to know what's the problem in my code
Please understand with my not good English
enter image description here
#!/bin/sh
i=2
while [ $i -le 100]
do
c=0
j=1
while [ $j -lt $i ]
do
if [ $(( $i % $j )) -eq 0 ]
then
c=$(( $c+1 ))
fi
j=$(( $j+1 ))
if [ $c -eq 0 ]
then
echo i
fi
done
i=$(( $i+1 ))
done
As shown by StephaneVeyret, the shebang shouldn't have spaces .
The purpose of the script seems to be printing numbers sequentially. If that is the case, you might want to take a look at a simple code like this :
#!/bin/bash
for i in {1..100}
do
printf "$i\n"
done
There should not be space in your shebang, between ! and /bin/sh. The first line of your script should be:
#!/bin/sh
(instead of #! /bin/sh)
Also, please note that if you really want to use Bourne shell, it should actually be:
#!/bin/bash
EDIT1: more problems:
As you want to use bash, you'd better use double brackets in your conditional statement, i.e.:
if [[ $j -le $i ]]
because they are more “powerful” in bash.
For this particular expression, you could also do:
if (( j <= i ))
Now, be careful to put spaces after [[ and (( and before ]] and )), and around operators:
$j=$(( $i + 1 ))
There seem to also be algo problems, but I don't have time to re-create your script and will check them only if I can copy-paste on my computer. Can you please paste an updated version of your script in your question? That would be easier for us than working on an image.
EDIT2: re your last post:
Line 4: there is a missing space before the closing bracket:
while [ $i -le 100 ]
Now, if you want to know what the script is doing, you can add the following command, for example, just after the shebang:
set -x
There are a few technical problems with your code, and also (if I understand what you are trying to do correctly) some logical errors in the design.
I'll share a few comments about how I looked at this. First thing to note is that the code you show is inconsistently indented, which means it is hard to see the logical structure of the code by simply looking at it. I loaded this into my usual editor (VSCode) which has a handy "Format Document" feature (many other code editors have similar auto-format features), and that produced the following:
#!/bin/sh
i=2
while [ $i -le 100]; do
c=0
j=1
while [ $j -lt $i ]; do
if [ $(($i % $j)) -eq 0 ]; then
c=$(($c + 1))
fi
j=$(($j + 1))
if [ $c -eq 0 ]; then
echo i
fi
done
i=$(($i + 1))
done
Note how this properly shows the nesting of statements within the inner while loop, in contrast to the original code. Even if you don't have access to a fancy editor, it is worthwhile spending the time to ensure that your code is manually indented correctly. It will save you a lot of time later in understanding and debugging the code.
Note also that the echo i line towards the end of the code should be echo $i if you want to print the value of the i variable.
When I try to run this code, it actually gives me an error telling me there's a missing ] in line 4. You need a space after the 100 here (as also pointed out by Stéphane Veyret):
while [ $i -le 100 ]; do
Next up, I added extra echo lines at various points in the code just to debug it. For example, the first thing I tried was to add the following line just before the final done line (the last line of the code)
echo "i=" $i
When I run the code I see this message printed multiple times, which tells me that the loop is running and that i is getting incremented from 2 to 100 as expected. I then added further echo lines at places within the while loop to check the values of other variables too.
These investigations highlighted a problem in your logic in the line
if [ $(($i % $j)) -eq 0 ]; then
The variable j is set to 1 at the start of each pass of the outer while loop. Any number modulus 1 is equal to zero, so this test will always be true when j is 1. This means that c will always be incremented the first time this code is encountered in each pass of the outer while loop (c=$(($c + 1))). And that means that the following test (if [ $c -eq 0 ]; then) will never be true.
I hope that gives you some ideas of what the problems are and how to go about further testing and debugging the code to make it do what you want.

Am I using the correct syntax for my shell script? [duplicate]

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Command not found error in Bash variable assignment
(5 answers)
Closed 4 years ago.
I wrote a shell script that gets a value from a file and based on that value I want to echo a particular message. My console keeps on saying that there is an error on line 7 and 9. Any suggestions on how to fix it will be greatly appreciated.
export JAVA_HOME='/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home'
echo $JAVA_HOME
export CLASSPATH='/Users/edgarjohnson/Desktop/JarFiles/mlDownload.jar:/ddc/config'
echo $CLASSPATH
var=$(cat /ddc/config/LastRefreshDate.dat)
echo $var
if [$var > 0 ];then
echo "Run Get Latest Update Class"
elif [$var = 0]; then
echo "No need to run any updates"
fi
After [ and before ] there must be a space. Otherwise the variable is substituted and the shell will try to execute a program called [Whatever.
[ itself is actually just a binary which is executed with var's content, =, 0 and ] as arguments and its return code is used to determine whether the if or else branch should be taken.
However the operators used are not really the ones you intend to use, e.g. > is interpreted as shell redirect creating a file called 0 (or overwritting it) and is not actually comparing anything, use -gt instead. = checks string equality, -eq checks value equality.
As mentioned in the comments it may be better to use [[ ]] instead of [ ].

String comparison does not work in Shell [duplicate]

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 5 years ago.
I'm pretty new to shell programming languages. Why does the following code echo false after printing "File or directory not found."?
#!/bin/sh -xu
ARG_PATH="/srv/path/to/Something"
if ["$ARG_PATH" = "/srv/path/to/Something"]
then
echo "true!"
else
echo "false!"
fi
I've tried running the code in sh and bash, doesn't really change anything.
check whether path is correct or not ? your syntax is seems okay except Bash is space sensitive give the space after [ and before ]
ARG_PATH="/srv/path/to/Something"
if [ $ARG_PATH = "/srv/path/to/Something" ]
then
echo $? #display 0 if both r same
fi
Put spaces around the bracket, if you don't the shell will think ["$ARG_PATH" is the command when it should be [.
The correct test thus is if [ "$ARG_PATH" = "/srv/path/to/Something" ]

Linux Shell Scritping - checking arguments [duplicate]

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 6 years ago.
Trying to make a program where it takes two arguments from the command line and adds them together. However if there are not two arguments passed it needs to ask for two arguments.
if [$# = 2]; then
ans=$(($1 + $2))
echo "$1 + $2 = $ans"
else
echo "Pass me two Arguments!"
fi
What is the correct way to check whether the number of arguments is equivalent to a number?
You got it but just forgot some escaping quotes and the spaces before/after the test ([$# = 2]). Fixed:
if [ "$#" = 2 ]; then
ans=$(($1 + $2))
echo "$1 + $2 = $ans"
else
echo "Pass me two Arguments!"
fi
Odd as it may seem, [ is actually the name of an executable just like echo, ls and what have you:
$ which [
/usr/bin/[
This means that if you don't have a space after [, you're trying to start a program called [your_statement. The space is needed to separate the executable from its arguments.
Most *nix systems allow you to use the equivalent test executable rather than [ for a more intuitive syntax: if test "$#" = 2; then ...
By omitting the quotes in the if statement, bash/shell interprets everything following the # as a comment and so does SO's code formatting tool (everything after if [$ is greyed out in your code but not in mine because I added the double quotes in "$#").
Btw. ShellCheck can be very helpful.

"test: too many arguments" message because of special character * while using test command on bash to compare two strings [duplicate]

This question already has answers here:
Meaning of "[: too many arguments" error from if [] (square brackets)
(6 answers)
Closed 5 years ago.
I'm new to shell scripting and I'm having some trouble while using the "test" command and the special character * to compare two strings.
I have to write a shell script which, for every element(both files and directories) contained in the directory passed as the first argument, has to write something(for the solving of my problem it is not relevant to know what has to be written down) on the file "summary.out". What's more, there's a string passed as the second argument. Those files/directories beginning with this string must be ignored(nothing has to be written on summary.out).
Here is the code:
#!/bin/bash
TEMP=NULL
cd "$1"
for i in *
do
if test "$i" != "$2"*;then #Here is where the error comes from
if test -f "$i";then
TEMP="$i - `head -c 10 "$i"`"
elif test -d "$i";then
TEMP="$i - `ls -1 "$i" | wc -l`"
fi
echo $TEMP >> summary.out
fi
done
The error comes from the test which checks whether the current file/directory begins with the string passed as second argument, and it takes place every iteration of the for cycle. It states:"test: too many arguments"
Now, I have performed some tests which showed that the problem has nothing to do with blank spaces inside the $i or $1. The problem is linked to the fact that I use the special character * in the test(if I remove it, everything works fine).
Why can't "test" handle * ? What can I do to fix that?
* gets expanded by the shell.
In bash, you can use [[ ... ]] for conditions instead of test. They support patterns on the right hand side - * is not expanded, as double square brackets are a keyword with higher precedence.
if [[ a == * ]] ; then
echo Matches
else
echo Doesn\'t match
fi

Resources