So I'm writing a bash shell script, and my first few lines looks like this:
if ! [ $# -eq 0 || $# -eq 1 ]; then
echo -e "Usage: myScriptName [\e[3mdir\e[0m] [\e[3m-f file\e[0m]"
exit 1
fi
But when I run it, it says "[: missing `]'". I don't see a missing ], and nothing except the ; is touching the ], so what am I missing?
You cannot use operators like || within single-brace test expressions. You must either do
! [[ $# -eq 0 || $# -eq 1 ]]
or
! { [ $# -eq 0 ] || [ $# -eq 1 ]; }
or
! [ $# -eq 0 -o $# -eq 1 ]
The double-brace keyword is a bash expression, and will not work with other POSIX shells, but it has some benefits, as well, such as being able to do these kinds of operations more readably.
Of course, there are a lot of ways to test the number of arguments passed. The mere existence of $2 will answer your question, as well.
In my case I got this error with the following:
if [ $# -eq 1]; then
Notice that there is no space between the 1 and the ]. Adding a space fixed the error.
In some cases this error happens even if everything looks fine as #kojiro mentioned above. in such cases a simple and proper line-break will help. if-statement where you are checking with || should have a line-break from it's prior-line of code.
Related
I wrote a small korn script, but when I try to run the script, it will not echo the message I want to display. When I try to run it by
ksh script.sh -1
it is not echoing the message.
if [ $# -le 0 ]
then
echo "That is a negative integer!"
exit
fi
In bash/ksh $# represents the number of arguments passed as parameters.
What you needed is
if [ ${1:-0} -lt 0 ] # $1 is the first parameter
then
echo "That is a negative integer!"
exit
fi
Or a shorted version of the above
[ ${1:-0} -lt 0 ] && echo "That is a negative integer!" && exit
Edit 1
I have used shell [ parameter expansion ] ${1:-0} supply a default value.
Since zero is technically not a negative number, replace -le with -lt
Edit 2
If you're looking forward to match a particular string then do below
[ ${1:-NULL} = "StringToMatch" ] && DoSomething
If you're looking to see if the output is just has atleast one non-digit character,then do something like below
[[ {1:-NULL} =~ [^[:digit:]]+ ]] && DoSomething
Warning : Not all expansions mentioned in the link may not be supported by ksh
When running my script I get the following error:
unexpected 'else' syntax error.
Everything seems fine to me
#!/bin/bash
#
#
if [$#>1] then
perl blockingsessionsprojse.pl $1
else
perl blockingsessionsprojse.pl 300
fi
There are 2 errors in your code. First of all, you use if keyword wrong.
$ help if
if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
Note the ;. So it should be:
if [$#>1]; then
Second, you need add a whitespace after [ and before ], and also around the > operator (which needs to be -gt for numeric comparisons) so altogether if condition should be:
if [ $# -gt 1 ]; then
Try :
if [ $# -gt 1 ]
then
perl blockingsessionsprojse.pl $1
else
perl blockingsessionsprojse.pl 300
fi
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
I am new in shell script, trying to catch the return value of a program, and do something with it.
I have this script below
#!/bin/sh
if [ $# !=2 ] ; then
echo "Usage : param1 param2 "
exit 1;
elif [ $# -eq 2 ]; then
./callprogram
$out = $?
echo "$out"
fi
if [ $out==0 ]; then
echo "out ok"
fi
It keeps getting me error of
"[: 11: 0: unexpected operator
out ok
I have no clue why line 11 is wrong. if I remove "fi", it will promt that it needs "fi". Can anyone help with this matter?
Thank you
You need a space after the [ and you need to use -eq (equals) or -ne (not equals) to compare numbers in your if-statement.
To assign a variable use out=$?, not $out = $?. There should be no spaces on either side of the = sign.
Try this:
if [ $# -ne 2 ] ; then
echo "Usage : param1 param2 "
exit 1
elif [ $# -eq 2 ]; then
./callprogram
out=$?
echo "$out"
fi
if [ $out -eq 0 ]; then
echo "out ok"
fi
Change:
if [ $out==0 ]; then
to:
if [ $out = 0 ]; then
add spaces, and change '==' to '='. Note, that bash, executed as a bash accepts ==. But if you run is as a sh it will say "unexpected operator".
Why:
The [ is a command (or symlink to test binary, depending on your OS and shell). It expects $out and == and 0 and ] to be separate command arguments. If you miss the space around them, you have one argument $out==0.
BTW:
It's safer to always enquote the variables like that:
if [ "$var" ......
instead of
if [ $var
because when variable is empty, then you can get another error because of wrong number of arguments (no argument instead of empty string).
You have several problems. The one that is giving you the error is that you need a space after != on
if [ $# != 2 ]
(although -ne would be better than !=). It appears that you are calling the script with 11 arguments, and then calling [ with the arguments 11 !=2, and it does not know what to do with !=2 because you meant != 2 but forgot the space. Also, you want
out=$?
on the assignment (no $ on the LHS)
and
if [ $out = 0 ]
on the comparison. (Spaces around the operator, which is '=' instead of '=='. '==' will work on many shells, but '=' works in more shells.)
But your script would be better written without the explicit reference to $?
#!/bin/sh
if test $# != 2; then
echo "Usage: $0 param1 param2 " >&2 # Errors go to stderr, not stdout
exit 1;
fi
# you know $# is 2 here. No need to check
if ./callprogram; then
echo "out ok"
fi
This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 6 years ago.
I wrote a function in bash script. However, it's complaining about syntax. I really can't see what is it..... the error message is [: missing `]'
addem() {
if [ $# -eq 0] || [ $# -gt 2 ]
then
echo -1
elif [ $# -eq 1 ]
then
echo $[ $1 + $1 ]
else
echo $[ $1 + $2 ]
fi
}
You need a space before the first ]. That is:
change:
if [ $# -eq 0] || [ $# -gt 2 ]
to:
if [ $# -eq 0 ] || [ $# -gt 2 ]
Try:
if [ $# -eq 0 ] || [ $# -gt 2 ]
(There was no space between 0 and ].)
indyK1ng: The "#" is not treated as a comment, since the "$" escapes the next character. The "$#" is an internal variable representing the number of positional parameters that exist at the current context. This can be thought of as the number of command line arguments to the shell script, but that array can be reset using the "set -- [args]" built in.
Joakim Elofsson: The overall structure of the if statement is correct, the ";" is only required before the "then" and before the "fi" if those are not listed on a separate line.
The problem is the space between the "0" and the bracket. Bash requires that brackets used to delimit conditional expressions be set off with at least a single space from the expression.
if [ $# -eq 0] || [ $# -gt 2 ] # Wrong
if [ $# -eq 0 ] || [ $# -gt 2 ] # Correct
On an additional note, the two conditional expressions can be combined. The operator association will ensure that everything works out.
if [ $# -eq 0 -a $# -gt 2 ] # Even Better
I tend to prefer the expanded features offered with double brackets for expression evaluation. Note that the combination of the two evaluations is done with a different operator. I find this to be more readable.
if [[ $# -eq 0 || $# -gt 2 ]] # My preference
Later in the script, the use of single brackets for integer addition is not recommended. The single brackets are evaluating an expression to a boolean. Double parens are used for integer math.
echo $[ $1 + $1 ] # Evaluation of an expression
echo $(( $1 + $1 )) # Integer math
Bash is sensitive to spaces. In your first line, replace if [ Y -eq X] with [ Y -eq X ] (space before the "]")
I would use extended test constructs (BASH) as demonstrated bellow. I think it would reduce the no of characters and increase readability (at least for programmers). :-)
addem() {
if (( $# == 0 || $# > 2 ))
then
echo -1
elif (( $# == 1 ))
then
echo (( $1 + $1 ))
else
echo (( $1 + $2 ))
fi
}
You should avoid brackets and use test instead:
if test $# -eq 0 || test $# -gt 2
then
echo -1
elif test $# -eq 1
then
echo $(( $1 + $1 ))
else
echo $(( $1 + $2 ))
fi
Getting a better shell style will make you much better. :)