This question already has answers here:
what is wrong with my unix script
(5 answers)
Closed 9 years ago.
#!/bin/bash
while echo -n "Player's name?"
read name
[ $name != 'ZZZ' ]
do
searchresult=$(grep [$name] playername)
if [ $searchresult=0 ]
then
echo -n "if See target (T/t) or team name (M/m)?"
read team
read target
while [ [ $target!=T ] || [ $team!=M ] ]
do
echo "Please enter only T or M."
done
if $target=T
then
grep [ $name ] targetselected
else
grep [ $name ] teamselected
fi
else
echo 'no such player'
fi
done
echo You are now exited search
error msg - line 10: [: too many arguments, what is that mean?
Not sure which line 10 in posted code you are pointing to but I found few issues with your posted code as
the line while [ [ $target!=T ] || [ $team!=M ] ] should be
while [ $target!="T" ] || [ $team!="M" ]
Also, if $target=T should accordingly be if $target="T"
The two lines:
searchresult=$(grep [$name] playername)
if [ $searchresult=0 ]
are very wrong. If you are trying to determine if the grep succeeds, it is best to do:
if grep -q "$name" playername; then ...
Putting grep in $() and assigning to searchresult has you comparing the output of grep rather than checking its exit status. And the spaces that are missing around the = in the second line are very wrong. Assuming searchresult is a string that contains no whitespace and only alphanumeric characters, the line if [ $searchresult=0 ] will always evaluate to true because the string "$searchresult=0" is always non-empty. (If searchresult is the empty string then $searchresult=0 is the string =0 which is non-empty, so the test succeeds.) It is highly unlikely that you intend to be testing whether or not that string is empty. The exact error that you are seeing indicates that the grep is assigning a value to searchresult which contains whitespace. In that case [ $searchresult=0 ] (without double quotes around $searchresult) is being parsed by [ as multiple arguments (split on the whitespace in $searchresult), and the error is telling you that there are too many arguments.
Related
This question already has answers here:
Why does 'test -n' return 'true' in bash?
(2 answers)
Closed 2 years ago.
When $thing is null this quits...
thing=`command_that_could_return_null`
echo "thing is" $thing
if [ -z $thing ]; then exit; fi
...but this...
if [ -n $thing ] && [ $thing = "special_value" ]; then
do_the_special_thing
fi
comes out with
[: =: unexpected operator
I don't understad.
When $thing is null the first factor of the && evaluates to false and therefore the second should not be evaluated, but it appears that it is being evaluated?
I guess it's just a feature of sh that I have to write this as two ifs?
If you fix your quote problem (which #CharlesDuffy mentioned) - your bottom 3 lines work just fine:
if [ -n "$thing" ] && [ "$thing" = "special_value" ]; then
do_the_special_thing
fi
Also, you referred to variables being "null", but the relevant term is a variable that is "unset". In Bourne shell terminology, "null" refers to the empty string.
This question already has answers here:
Why equal to operator does not work if it is not surrounded by space?
(4 answers)
Closed 5 years ago.
I tried to compare user input between to string
Here is my code
Encode="Encode"
Decode="Decode"
printf "Enter name of file: "
read fileName
printf "Encode Or Decode: "
read EncOrDec
if [ "$Encode"=="$EncOrDec" ]; then
printf "Encode Nice\n"
elif [ "$Decode"=="$EncOrDec" ]; then
printf "Decode Nice\n"
else
printf "Nothing\n"
fi
Its always go to the Encode statement, Why?.
And how to fix it
In bash, spaces count. Replace:
if [ "$Encode"=="$EncOrDec" ]; then
With:
if [ "$Encode" = "$EncOrDec" ]; then
Without spaces, bash is just testing whether the string "$Encode"=="$EncOrDec" is empty or not. Since it is never empty, the then clause is always executed.
Also, as a minor detail, when using [...], the use of = for string equality is POSIX standard. Bash accepts == but == is not standard and won't be reliably portable.
The same applies to the elif line. Replace:
elif [ "$Decode"=="$EncOrDec" ]; then
With:
elif [ "$Decode" = "$EncOrDec" ]; then
I'm working with shell scripts.
I'm in the test section, where if an argument is passed:
The expression is true if, and only if, the argument is not null
And here I have implemented the following code:
[ -z $num ]; echo $?;
Your exit:
0
Why?
Firstly, [-z should be [ -z, otherwise you would be getting an error like [-z: command not found. I guess that was just a typo in your question.
It sounds like you're quoting the wrong part of the manual, which would apply to tests like this:
[ string ] # which is equivalent to
[ -n string ]
Either of which would return success (a 0) for a non-empty string.
With -z, you're checking that the length of the string is 0.
However, as always, be careful with unquoted variables, since:
[ -z $num ]
# expands to
[ -z ]
# which is interpreted in the same way as
[ string ]
i.e. your test becomes "is -z a non-empty string?", to which the answer is yes, so the test returns 0. If you use quotes around "$num" then the test does what you would expect.
I couldn't find any one simple straightforward resource spelling out the meaning of and fix for the following BASH shell error, so I'm posting what I found after researching it.
The error:
-bash: [: too many arguments
Google-friendly version: bash open square bracket colon too many arguments.
Context: an if condition in single square brackets with a simple comparison operator like equals, greater than etc, for example:
VARIABLE=$(/some/command);
if [ $VARIABLE == 0 ]; then
# some action
fi
If your $VARIABLE is a string containing spaces or other special characters, and single square brackets are used (which is a shortcut for the test command), then the string may be split out into multiple words. Each of these is treated as a separate argument.
So that one variable is split out into many arguments:
VARIABLE=$(/some/command);
# returns "hello world"
if [ $VARIABLE == 0 ]; then
# fails as if you wrote:
# if [ hello world == 0 ]
fi
The same will be true for any function call that puts down a string containing spaces or other special characters.
Easy fix
Wrap the variable output in double quotes, forcing it to stay as one string (therefore one argument). For example,
VARIABLE=$(/some/command);
if [ "$VARIABLE" == 0 ]; then
# some action
fi
Simple as that. But skip to "Also beware..." below if you also can't guarantee your variable won't be an empty string, or a string that contains nothing but whitespace.
Or, an alternate fix is to use double square brackets (which is a shortcut for the new test command).
This exists only in bash (and apparently korn and zsh) however, and so may not be compatible with default shells called by /bin/sh etc.
This means on some systems, it might work from the console but not when called elsewhere, like from cron, depending on how everything is configured.
It would look like this:
VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
# some action
fi
If your command contains double square brackets like this and you get errors in logs but it works from the console, try swapping out the [[ for an alternative suggested here, or, ensure that whatever runs your script uses a shell that supports [[ aka new test.
Also beware of the [: unary operator expected error
If you're seeing the "too many arguments" error, chances are you're getting a string from a function with unpredictable output. If it's also possible to get an empty string (or all whitespace string), this would be treated as zero arguments even with the above "quick fix", and would fail with [: unary operator expected
It's the same 'gotcha' if you're used to other languages - you don't expect the contents of a variable to be effectively printed into the code like this before it is evaluated.
Here's an example that prevents both the [: too many arguments and the [: unary operator expected errors: replacing the output with a default value if it is empty (in this example, 0), with double quotes wrapped around the whole thing:
VARIABLE=$(/some/command);
if [ "${VARIABLE:-0}" == 0 ]; then
# some action
fi
(here, the action will happen if $VARIABLE is 0, or empty. Naturally, you should change the 0 (the default value) to a different default value if different behaviour is wanted)
Final note: Since [ is a shortcut for test, all the above is also true for the error test: too many arguments (and also test: unary operator expected)
Just bumped into this post, by getting the same error, trying to test if two variables are both empty (or non-empty). That turns out to be a compound comparison - 7.3. Other Comparison Operators - Advanced Bash-Scripting Guide; and I thought I should note the following:
I used -e thinking it means "empty" at first; but that means "file exists" - use -z for testing empty variable (string)
String variables need to be quoted
For compound logical AND comparison, either:
use two tests and && them: [ ... ] && [ ... ]
or use the -a operator in a single test: [ ... -a ... ]
Here is a working command (searching through all txt files in a directory, and dumping those that grep finds contain both of two words):
find /usr/share/doc -name '*.txt' | while read file; do \
a1=$(grep -H "description" $file); \
a2=$(grep -H "changes" $file); \
[ ! -z "$a1" -a ! -z "$a2" ] && echo -e "$a1 \n $a2" ; \
done
Edit 12 Aug 2013: related problem note:
Note that when checking string equality with classic test (single square bracket [), you MUST have a space between the "is equal" operator, which in this case is a single "equals" = sign (although two equals' signs == seem to be accepted as equality operator too). Thus, this fails (silently):
$ if [ "1"=="" ] ; then echo A; else echo B; fi
A
$ if [ "1"="" ] ; then echo A; else echo B; fi
A
$ if [ "1"="" ] && [ "1"="1" ] ; then echo A; else echo B; fi
A
$ if [ "1"=="" ] && [ "1"=="1" ] ; then echo A; else echo B; fi
A
... but add the space - and all looks good:
$ if [ "1" = "" ] ; then echo A; else echo B; fi
B
$ if [ "1" == "" ] ; then echo A; else echo B; fi
B
$ if [ "1" = "" -a "1" = "1" ] ; then echo A; else echo B; fi
B
$ if [ "1" == "" -a "1" == "1" ] ; then echo A; else echo B; fi
B
Another scenario that you can get the [: too many arguments or [: a: binary operator expected errors is if you try to test for all arguments "$#"
if [ -z "$#" ]
then
echo "Argument required."
fi
It works correctly if you call foo.sh or foo.sh arg1. But if you pass multiple args like foo.sh arg1 arg2, you will get errors. This is because it's being expanded to [ -z arg1 arg2 ], which is not a valid syntax.
The correct way to check for existence of arguments is [ "$#" -eq 0 ]. ($# is the number of arguments).
I also faced same problem. #sdaau answer helped me in logical way. Here what I was doing which seems syntactically correct to me but getting too many arguments error.
Wrong Syntax:
if [ $Name != '' ] && [ $age != '' ] && [ $sex != '' ] && [ $birthyear != '' ] && [ $gender != '' ]
then
echo "$Name"
echo "$age"
echo "$sex"
echo "$birthyear"
echo "$gender"
else
echo "Enter all the values"
fi
in above if statement, if I pass the values of variable as mentioned below then also I was getting syntax error
export "Name"="John"
export "age"="31"
export "birthyear"="1990"
export "gender"="M"
With below syntax I am getting expected output.
Correct syntax:
if [ "$Name" != "" -a "$age" != "" -a "$sex" != "" -a "$birthyear" != "" -a "$gender" != "" ]
then
echo "$Name"
echo "$age"
echo "$sex"
echo "$birthyear"
echo "$gender"
else
echo "it failed"
fi
There are few points which we need to keep in mind
use "" instead of ''
use -a instead of &&
put space before and after operator sign like [ a = b], don't use as [ a=b ] in if condition
Hence above solution worked for me !!!
Some times If you touch the keyboard accidentally and removed a space.
if [ "$myvar" = "something"]; then
do something
fi
Will trigger this error message. Note the space before ']' is required.
I have had same problem with my scripts. But when I did some modifications it worked for me. I did like this :-
export k=$(date "+%k");
if [ $k -ge 16 ]
then exit 0;
else
echo "good job for nothing";
fi;
that way I resolved my problem. Hope that will help for you too.
this is a bash script. im getting the error in the if statement line
# 2. read a line of input from the keyboard
read answer
if [-z "$answer"]
then
$answer=$default
else
$default=$answer
fi
i don't do much bash anymore, i can't see the error, ive tried
if [-z "$answer"]; then
and that failed as well with the same error. can anyone else see the error?
EDIT UPDATE
i changed it to this
read answer
if [ -z "$answer" ]
then
$answer=$defaultEntry
else
$defaultEntry=$answer
fi
and the same error occures
simply leave spaces between the brackets and condition:
if [ -z "$answer" ]
There should be a space between [ and -z, and between " and ].
[ is an alias to the test program.
[ is a program, which bash can execute.
[-z isn't, thus an error.
You need spaces around [ and ]. E.g.:
if [ -z "$answer" ]
then
$answer=$default
else
$default=$answer
fi
The reason for this is that [ is actually a shell builtin command.
[me#home]$ type [
[ is a shell builtin
[me#home]$ which [
/usr/bin/[
If you omit the space after [, you're mangling the command name into something that does not exist.
[me#home]$ [ -z "something" ] # OK. calling command [ with some args
[me#home]$ [-z "something" ] # fail. calling command [-z with some args
-bash: [-z: command not found
The [ command also checks that the last argument is ], therefore if you don't have spaces around that it becomes part of the previous argument and the [ command will complain:
[me#home]$ [ -z "something" ] # this runs fine becuase last arg is ]
[me#home]$ [ -z "something"] # will fail. last arg is "something"]
-bash: [: missing `]'
The space around the [ and ] is important, as others have pointed out.
Also, you should not be using $ when assigning to a variable.
Try this:
read answer
if [ -z "$answer" ]
then
answer=$defaultEntry
else
defaultEntry=$answer
fi
read answer
if [ -z "$answer" ] #Spaces!
then
answer=$default # Use "answer" and not "$answer"
else
default=$answer # Use "default" and not "$default"
fi
This now works except that I don't have a value for $default. I suspect you've done that elsewhere (as well as set a prompt).