I was working though the examples here http://tldp.org/LDP/abs/html/debugging.html and would like some help explaining the internals of why this script throws the error [37: command not found
#!/bin/bash
# ex74.sh
# This is a buggy script.
# Where, oh where is the error?
a=37
if [$a -gt 27 ]
then
echo $a
fi
exit $? # 0! Why?
if [ $a -gt 27 ]
^
|
add space here
The reason for the spaces after [ is because [ is also not syntax. It is a simple command. Usually a builtin of the shell. The shell executes the command [ with the rest as parameters, including the ] as mandatory last parameter. If you do not put a space after [ the shell will try to execute [whatever as command and fail.
The reason for space before the ] is similar. Because otherwise it will not be recognized as a parameter of its own.
Related
Usually, I use square brackets in the if statement:
if [ "$name" = 'Bob' ]; then ...
But, when I check if grep succeeded I don't use the square brackets:
if grep -q "$text" $file ; then ...
When are the square brackets necessary in the if statement?
The square brackets are a synonym for the test command. An if statement checks the exit status of a command in order to decide which branch to take. grep -q "$text" is a command, but "$name" = 'Bob' is not--it's just an expression. test is a command, which takes an expression and evaluates it:
if test "$name" = 'Bob'; then ...
Since square brackets are a synonym for the test command, you can then rewrite it as your original statement:
if [ "$name" = 'Bob' ]; then ...
[ is actually a command, equivalent (almost, see below) to the test command. It's not part of the shell syntax. (Both [ and test, depending on the shell, are often built-in commands as well, but that doesn't affect their behavior, except perhaps for performance.)
An if statement executes a command and executes the then part if the command succeeds, or the else part (if any) if it fails. (A command succeeds if it exits with a status ($?) of 0, fails if it exits with a non-zero status.)
In
if [ "$name" = 'Bob' ]; then ...
the command is
[ "$name" = 'Bob' ]
(You could execute that same command directly, without the if.)
In
if grep -q "$text" $file ; then ...
the command is
grep -q "$text" $file
man [ or man test for more information.
FOOTNOTE: Well, the [ command is almost equivalent to the test command. The difference is that [ requires ] as its last argument, and test does not -- and in fact doesn't allow it (more precisely, test doesn't treat a ] argument specially; for example it could be a valid file name). (It didn't have to be implemented that way, but a [ without a matching ] would have made a lot of people very very nervous.)
The best way to think of the [ ... ] syntax, is to consider [ to be a program - which it is!
Check this out:
~ $ ls /usr/bin/\[
/usr/bin/[
on the other hand, you're probably not using that version of it since bash also provides [ as a shell built-in.
Anyway, to answer your question: What if does is run the command you give it and see it the return value is 0 or not. You use [ to do other, more interesting comparisons such as string comparisons. See man [ and man bash.
Usually, I use square brackets in the if statement:
if [ "$name" = 'Bob' ]; then ...
But, when I check if grep succeeded I don't use the square brackets:
if grep -q "$text" $file ; then ...
When are the square brackets necessary in the if statement?
The square brackets are a synonym for the test command. An if statement checks the exit status of a command in order to decide which branch to take. grep -q "$text" is a command, but "$name" = 'Bob' is not--it's just an expression. test is a command, which takes an expression and evaluates it:
if test "$name" = 'Bob'; then ...
Since square brackets are a synonym for the test command, you can then rewrite it as your original statement:
if [ "$name" = 'Bob' ]; then ...
[ is actually a command, equivalent (almost, see below) to the test command. It's not part of the shell syntax. (Both [ and test, depending on the shell, are often built-in commands as well, but that doesn't affect their behavior, except perhaps for performance.)
An if statement executes a command and executes the then part if the command succeeds, or the else part (if any) if it fails. (A command succeeds if it exits with a status ($?) of 0, fails if it exits with a non-zero status.)
In
if [ "$name" = 'Bob' ]; then ...
the command is
[ "$name" = 'Bob' ]
(You could execute that same command directly, without the if.)
In
if grep -q "$text" $file ; then ...
the command is
grep -q "$text" $file
man [ or man test for more information.
FOOTNOTE: Well, the [ command is almost equivalent to the test command. The difference is that [ requires ] as its last argument, and test does not -- and in fact doesn't allow it (more precisely, test doesn't treat a ] argument specially; for example it could be a valid file name). (It didn't have to be implemented that way, but a [ without a matching ] would have made a lot of people very very nervous.)
The best way to think of the [ ... ] syntax, is to consider [ to be a program - which it is!
Check this out:
~ $ ls /usr/bin/\[
/usr/bin/[
on the other hand, you're probably not using that version of it since bash also provides [ as a shell built-in.
Anyway, to answer your question: What if does is run the command you give it and see it the return value is 0 or not. You use [ to do other, more interesting comparisons such as string comparisons. See man [ and man bash.
this script tries to ping through a hosts string array.
for i in "${arr[#]}"
do
echo "check if $i is online"
ping -c1 $i &>/dev/null
if[ $? -eq 0 ] then
echo "$i is online"
else
echo "$i is not online"
fi
done
I am new to bash scripting so if some one could tell me why I get an
syntax error near unexpected token `else'
and also if this is a good approach. Thanks in advance
[ is not part of bash's syntax; it is a regular character like a or 8. As such, the parser does not recognize if[ as two words if and [; it just sees the name if[, which it assumes might be a command name followed by a series of arguments terminated by the end of the line. The following line is also a valid command. The next line, though, begins with else, which is a recognized keyword and thus cannot occur in command position, but only as part of an on-going if statement, triggering the error.
All of which is to say, you must separate if and [ with a space.
if [ $? -eq 0 ]; then
(You also need a semi-colon before then if it appears on the same line, which would be the next problem you encountered after fixing the space issue.)
The line number 6, should have been with a semi-colon ; and need a space after the if in if[ $? of your line.
if [ $? -eq 0 ]; then
More recommended way is you can directly use ping's exit-code in if-statement as
if ping -c 1 "$i" &> /dev/null
then
echo "$i is online"
else
echo "$i is not online"
fi
See the below excerpt from the man ping page on why I used the -c flag.
-c count
Stop after sending count ECHO_REQUEST packets. With deadline option, ping waits for count ECHO_REPLY packets, until the timeout expires.
Use http://www.shellcheck.net/ , to debug such trivial syntax errors.
if [ $? -eq 0 ]; then You need to have a space between the if and the [ and also you missed a ;
I don't know bash well but this seems pretty basic, yet I'm stuck on it. I'm using the bash installed on Mac OS X. I'm simply trying to test 1 command line argument and this is what I have and it doesn't work.
if [$1 -eq 'clean']
then
echo "Your argument is 'clean'!"
fi
Every time I've tried it, bash gives me a command not found error.
I'm obviously doing something wrong, what is it?
Couple of issues here:
Spaces around [ and ] are required in shell
-eq is used for comparing integers not for strings
Try this instead:
if [[ "$1" == "clean" ]]; then
echo "Your argument is 'clean'!"
fi
If you are using bash then [[ and ]] are more efficient than [ and ]
This question already has answers here:
How do I compare two string variables in an 'if' statement in Bash? [duplicate]
(12 answers)
Closed 7 years ago.
I'm at a loss as to why this is giving a syntax error. Any thoughts?
#!/bin/bash
if [ `date +%H` -lt 11 ] ; then exit 0;
fi
if [ `date +%H` -gt 14 ] ; then
if[ `date +%H` -lt 20 ] ; then # <--- this line is the culprit, it seems
exit 0;
fi
fi
When run, I get:
./get.sh: line 7: syntax error near unexpected token `then'
./get.sh: line 7: ` if[ `date +%H` -lt 20 ] ; then '
The reason that this is a syntax error is that [ isn't part of the shell syntax; it's actually a command. Originally it was just a symlink to the test command. It still is, but it's also a built-in command in bash and other Bourne-derived shells.
if is a shell keyword, but the shell sees if[, not if. Because it didn't see an if, it doesn't know what to do when it sees then. (Actually, it knows exactly what to do: print a syntax error message.)
...
A bit of experimentation shows that it's not quite as simple as I thought it was. I tried creating a command called if[ and putting it in a directory in my $PATH. When I type just if[ at the prompt, the shell asks for more input. I actually don't know what it's looking for, but apparently the [ character is specially treated by the shell. The shell just doesn't split if[ into the if keyword and the [ command (as you might reasonably expect based on how other languages work). (If I really wanted to execute that command, I could type \if[ or "if[" -- or give it a sane name in the first place.
In any case, that last part probably doesn't matter; adding a space character will fix the problem.
Add space before [
if [ `date +%H` -lt 20 ]
if[ `date +%H` -lt 20 ] ;
you need to place a space after if
if [ `date +%H` -lt 20 ] ;