I am learning Korn shell which is based on Bourne shell. Below is my really simple code.
read ab
if [ $ab = "a" || $ab = "A" ] ; then
echo hi
fi
For some reason || operator is giving me the error:
[: missing `]'
a: command not found
The correct way to write your if condition is:
read ab
if [ "$ab" = "a" ] || [ "$ab" = "A" ]; then
echo hi
fi
With [ ... ], it is essential to put the variables in double quotes. Otherwise, shell will fail with a syntax error if the variables expand to nothing or if their expansion contains spaces.
See also:
Why should there be a space after '[' and before ']' in Bash?
How to use double or single brackets, parentheses, curly braces
BashFAQ - What is the difference between test, single, and double brackets?
If you use ksh or a modern bash you can use the non-standard [[ ... ]] instead of [ ... ].
This has two benefits:
You can use || inside [[ ... ]]
Variable expansions do not need quotes.
This makes it safe and shorter to write
[[ $ab = a || $ab = A ]]
Related
My whole script is currently this:
#!/bin/sh
clear;
blanko="";
# Dummy-Variablen
variable=Testvariable;
if [[$variable == $blanko]];
then
echo "Nichts da!"
else
echo $variable
fi
and if I enter
TestSelect.sh
I get
/usr/bin/TestSelect.sh: line 6: [[Testvariable: command not found
Testvariable
How can I fix this?
This is problem:
if [[$variable == $blanko]];
Spaces are required inside square brackets, use it like this:
[[ "$variable" == "$blanko" ]] && echo "Nichts da!" || echo "$variable"
On a related note, spaces are required around [ ] as well:
if [ "$variable" = "$blanko" ]; then
# more code here
fi
Note that variables do need to be enclosed in double quotes inside [ ] to prevent word splitting and globbing. Double quotes also help when either of the variables being compared is not set - shell will throw a syntax error otherwise.
Look at the following post to understand why we need spaces around [ ]:
Why should there be a space after '[' and before ']' in Bash?
Another related post that talks about other syntax elements that need spaces as well:
Why is whitespace sometimes needed around metacharacters?
Finally, this post talks about the difference between [[ ]] and [ ]:
Difference between single and double square brackets in Bash
Related:
“0: command not found” in Bash
Just use #!/bin/bash on tope of script if you are using bash scripting like: if [[ $partition == "/dev/sda2" ]]; then to compare string and run script with ./scriptname.sh or bash scriptname.sh
If your script runs on your local with /bin/bash but not on your container with sh, then consider adding bash to your container by apk add --no-cache bash.
My whole script is currently this:
#!/bin/sh
clear;
blanko="";
# Dummy-Variablen
variable=Testvariable;
if [[$variable == $blanko]];
then
echo "Nichts da!"
else
echo $variable
fi
and if I enter
TestSelect.sh
I get
/usr/bin/TestSelect.sh: line 6: [[Testvariable: command not found
Testvariable
How can I fix this?
This is problem:
if [[$variable == $blanko]];
Spaces are required inside square brackets, use it like this:
[[ "$variable" == "$blanko" ]] && echo "Nichts da!" || echo "$variable"
On a related note, spaces are required around [ ] as well:
if [ "$variable" = "$blanko" ]; then
# more code here
fi
Note that variables do need to be enclosed in double quotes inside [ ] to prevent word splitting and globbing. Double quotes also help when either of the variables being compared is not set - shell will throw a syntax error otherwise.
Look at the following post to understand why we need spaces around [ ]:
Why should there be a space after '[' and before ']' in Bash?
Another related post that talks about other syntax elements that need spaces as well:
Why is whitespace sometimes needed around metacharacters?
Finally, this post talks about the difference between [[ ]] and [ ]:
Difference between single and double square brackets in Bash
Related:
“0: command not found” in Bash
Just use #!/bin/bash on tope of script if you are using bash scripting like: if [[ $partition == "/dev/sda2" ]]; then to compare string and run script with ./scriptname.sh or bash scriptname.sh
If your script runs on your local with /bin/bash but not on your container with sh, then consider adding bash to your container by apk add --no-cache bash.
My whole script is currently this:
#!/bin/sh
clear;
blanko="";
# Dummy-Variablen
variable=Testvariable;
if [[$variable == $blanko]];
then
echo "Nichts da!"
else
echo $variable
fi
and if I enter
TestSelect.sh
I get
/usr/bin/TestSelect.sh: line 6: [[Testvariable: command not found
Testvariable
How can I fix this?
This is problem:
if [[$variable == $blanko]];
Spaces are required inside square brackets, use it like this:
[[ "$variable" == "$blanko" ]] && echo "Nichts da!" || echo "$variable"
On a related note, spaces are required around [ ] as well:
if [ "$variable" = "$blanko" ]; then
# more code here
fi
Note that variables do need to be enclosed in double quotes inside [ ] to prevent word splitting and globbing. Double quotes also help when either of the variables being compared is not set - shell will throw a syntax error otherwise.
Look at the following post to understand why we need spaces around [ ]:
Why should there be a space after '[' and before ']' in Bash?
Another related post that talks about other syntax elements that need spaces as well:
Why is whitespace sometimes needed around metacharacters?
Finally, this post talks about the difference between [[ ]] and [ ]:
Difference between single and double square brackets in Bash
Related:
“0: command not found” in Bash
Just use #!/bin/bash on tope of script if you are using bash scripting like: if [[ $partition == "/dev/sda2" ]]; then to compare string and run script with ./scriptname.sh or bash scriptname.sh
If your script runs on your local with /bin/bash but not on your container with sh, then consider adding bash to your container by apk add --no-cache bash.
My whole script is currently this:
#!/bin/sh
clear;
blanko="";
# Dummy-Variablen
variable=Testvariable;
if [[$variable == $blanko]];
then
echo "Nichts da!"
else
echo $variable
fi
and if I enter
TestSelect.sh
I get
/usr/bin/TestSelect.sh: line 6: [[Testvariable: command not found
Testvariable
How can I fix this?
This is problem:
if [[$variable == $blanko]];
Spaces are required inside square brackets, use it like this:
[[ "$variable" == "$blanko" ]] && echo "Nichts da!" || echo "$variable"
On a related note, spaces are required around [ ] as well:
if [ "$variable" = "$blanko" ]; then
# more code here
fi
Note that variables do need to be enclosed in double quotes inside [ ] to prevent word splitting and globbing. Double quotes also help when either of the variables being compared is not set - shell will throw a syntax error otherwise.
Look at the following post to understand why we need spaces around [ ]:
Why should there be a space after '[' and before ']' in Bash?
Another related post that talks about other syntax elements that need spaces as well:
Why is whitespace sometimes needed around metacharacters?
Finally, this post talks about the difference between [[ ]] and [ ]:
Difference between single and double square brackets in Bash
Related:
“0: command not found” in Bash
Just use #!/bin/bash on tope of script if you are using bash scripting like: if [[ $partition == "/dev/sda2" ]]; then to compare string and run script with ./scriptname.sh or bash scriptname.sh
If your script runs on your local with /bin/bash but not on your container with sh, then consider adding bash to your container by apk add --no-cache bash.
Can someone please explain why this command returns an error (on Solaris ksh):
if [ "(" = "(" ]; then echo 1;fi;
ksh: test: argument expected
The same using bash is OK, and echoes "1" as expected
Also, using [[ ]] is OK.
The problem seems to be the first "("
That command seems to work on my ksh.
However, IIRC in ksh it's recommended to use [[ ]] instead of [ ]. So for a portable solution, I suggest you write it as:
if [[ "(" = "(" ]]; then echo 1; fi;
Do note however that [[]] is subtly different from [] in that wildcard expansions are not done. See http://www.bolthole.com/solaris/ksh-builtins.html#test
Update
For better portability to different shells, I tend to use the built-in test command which in ksh should have the exact same effect as [[]].
if test "(" = "("; then echo 1; fi
Does it work if you change the double quotes to single quotes -- i.e.,
if [ '(' = '(' ]; then echo 1;fi;
EDITED TO ADD: I've just been able to recreate the problem with a Digital UNIX ksh. Single quotes don't work either on this platform, however escaping the brackets does work:
if [ '\(' = '\(' ]; then echo 1;fi;
According to the man page for ksh, it states:
The following characters have a
special meaning to the shell and cause
termination of a word unless
quoted:
; & ( ) | ^ < > <newline> <space> <tab>
...and goes on to define more parsing rules. It seems that the ( is being interpreted as a special character even when quoted (oddly), hence the requirement for escaping. If you type "set -x" at the command line before you try your if, you'll see exactly what the shell is trying to do sent to stderr preceded with a '+' sign, which may help the tracing; e.g.:
$ set -x
$ if [ '(' = '(' ]; then echo 1;fi;
+ [ ( = ( ]
ksh: test: argument expected
$
$ if [ '\(' = '\(' ]; then echo 1;fi;
+ [ \( = \( ]
+ echo 1
1
$
It may be that it depends on the ksh implementation as well -- e.g., ksh-88 vs ksh-93 and later. On Digital UNIX, the implementation is ksh-88.