I am trying to execute the following shell script
#!/bin/sh
echo "start"
if [ $# != 2 || $1 != "first" || $1 != "second" ]
then
echo "Error"
fi
echo "done"
and I'm getting the following output:
start
./autobuild.sh: line 3: [: missing `]'
./autobuild.sh: line 3: !=: command not found
./autobuild.sh: line 3: !=: command not found
done
I have no idea how to resolve the errors. Even if I use -ne instead of !=, I get the same errors. Please help.
Your syntax is incorrect. If you want multiple conditions in an if statement you need to have multiple [] blocks. Try:
if [ $# != 2 ] || [ $1 != "first" ] || [ $1 != "second" ]
But, it's better to use [[ (if your shell supports it) as it is safer to use. I would go for:
if [[ $# -ne 2 || $1 != "first" || $1 != "second" ]]
See this question on brackets: Is [[ ]] preferable over [ ] in bash scripts?
While OR ing the conditions should be seperate as follows :
#!/bin/sh
echo "start"
if [ $# != 2] || [ $1 != "first" ] || [ $1 != "second" ]
then
echo "Error"
fi
echo "done"
Try substituting -NE for !=.
if-usage samples
This should work:
#!/bin/sh
echo "start"
if [ $# -ne 2 -o $1 -ne "first" -o $1 -ne "second" ]
then
echo "Error"
fi
echo "done"
Related
I want to detect if the 1st bash input parameter is "debug"(string).
I write script like this:
#! /usr/bin/env bash
if [ "$#" -eq "1" && "$1" -eq "debug" ]; then
echo "hello debug"
fi
Error message:
line 3: [: missing `]'
I don't know why, please help.
Compare strings with ==, -eq is an arithmetic operator. Also, within [] you have to use the -a operator instead of &&, or split it in two. Here are a few different ways to write the same thing:
if [[ $# -eq 1 && "$1" == "debug" ]] ; then
echo "hello debug"
fi
if [[ "$#" == "1" && "$1" == "debug" ]] ; then
echo "hello debug"
fi
if [ "$#" == "1" ] && [ "$1" == "debug" ] ; then
echo "hello debug"
fi
if [ "$#" == "1" -a "$1" == "debug" ] ; then
echo "hello debug"
fi
Instead of [ "$#" -eq "1" && "$1" -eq "debug" ], use either [ "$#" -eq "1" ] && [ "$1" -eq "debug" ] or [ "$#" -eq "1" -a "$1" -eq "debug" ]. The problem is that && is bash's way of saying "and", rather than -a, which is test's way of saying "and". You can't use a bash "and" inside of test.
When I run this bash script :
if [ [$EUID -ne 0] ]; then
echo "This script must be run as root" 1>&2
exit 1
else
printf " whathever "
exit 0
fi
I have this error :
./myScript: 15: [: Illegal number: [
Do you see any problem ?
You have syntax error in your if condition, use this if condition:
if [ "$EUID" -ne 0 ];
OR using [[ and ]]
if [[ "$EUID" -ne 0 ]];
You have syntax error in your if condition, use this if condition:
if [ "$EUID" -ne 0 ];
OR using [[ and ]]
if [[ "$EUID" -ne 0 ]];
If you use the KSH88+/Bash 3+ internal instruction [[, it's not necessary to use doubles quotes around the variables operands :
[ ~/test]$ [[ $var2 = "string with spaces" ]] && echo "OK" || echo "KO"
OK
Instead of the external command test or his fork [ :
[ ~/test]$ [ $var2 = "string with spaces" ] && echo "OK" || echo "KO"
bash: [: too many arguments
KO
[ ~/test]$ [ "$var2" = "string with spaces" ] && echo "OK" || echo "KO"
OK
Of course, you also have to choose the operators according to the type of operands :
[ ~/test]$ var1="01"
[ ~/test]$ [ "$var1" = "1" ] && echo "OK" || echo "KO"
KO
[ ~/test]$ [ "$var1" -eq "1" ] && echo "OK" || echo "KO"
OK
two suggestions apart from what everyone else has pointed out already.
rather than doing else [bunch of code because we are root] fi, just replace the else with fi. once you've tested for the failure condition you are concerned about and taken appropriate action, no need to continue to be within the body of the conditional.
$EUID is a bashism, if you would like to make this portable to shells such as ksh, replacing it with:
if [ $(id -u) -ne 0 ]; then echo "ur not root bro"; exit 1; fi
would be a good way to do it.
using
sudo bash shell_script.sh
instead of
sudo sh shell_script.sh
solved in my case.
I am trying to validate users input to a small script I am writing that checks that there should be: 2 arguments and the the first argument should be wither 'mount' or ' unmount'
I have the following:
if [ ! $# == 2 ] || [ $1 != "mount" -o $1 != "unmount" ]; then
However it seems to be a bit overzelouse at meeting the conditions I want. For example with the current || operator, nothing gets past the validator but if I use the && operator everything does.
if [ ! $# == 2 ] && [ $1 != "mount" -o $1 != "unmount" ]; then
Can someone help me figure this out?
Here is the whole block and intended usage
if [ ! $# == 2 ] || [ $1 != "mount" -o $1 != "unmount" ]; then
echo "Usage:"
echo "encmount.sh mount remotepoint # mount the remote file system"
echo "encmount.sh unmount remotepoint # unmount the remote file system"
exit
fi
You could do it like this:
if [ "$#" -ne 2 ] || [ "$1" != "mount" -a "$1" != "unmount" ]; then
echo "Usage:"
echo "encmount.sh mount remotepoint # mount the remote file system"
echo "encmount.sh unmount remotepoint # unmount the remote file system"
exit -1
fi
echo "OK"
You have a small logical error in your test, since you should enter the usage branch if $1 is not equal to both "mount" and "unmount". Also you should compare numbers with the -eq and -ne operators (see here), or use the (( )).
Note that you should quote your variables inside a test ([ ])
You can also combine the two expressions like this:
if [ "$#" -ne 2 -o \( "$1" != "mount" -a "$1" != "unmount" \) ]; then
If you have bash, you can also use the [[ ]] syntax:
if [[ $# -ne 2 || ( $1 != "mount" && $1 != "unmount" ) ]]; then
Here is my statements:
print "Ss $# $2" >&3
if [ $# -eq 4 || $# -eq 3 ] && [ $2 != "d" ]
then
print "sss"
else
print "lol"
fi
The output is:
Ss 4 s
lol
Why is "sss" not being displayed?
Your if-condition isn't syntactically correct. You can't have || inside the brackets. Change it to use -o instead:
if [ $# -eq 4 -o $# -eq 3 ] && [ $2 != "d" ]
then
print "sss"
else
print "lol"
fi
Or, even better, use [[ (if your shell supports it) which is safer and has more features. It supports ||:
if [[ ( $# -eq 4 || $# -eq 3 ) && $2 != "d" ]]
then
print "sss"
else
print "lol"
fi
How can I consolidate the following if statements into a single line?
if [ $# -eq 4 ]
then
if [ "$4" = "PREV" ]
then
print "yes"
fi
fi
if [ $# -eq 3 ]
then
if [ "$3" = "PREV" ]
then
print "yes"
fi
fi
I am using ksh.
Why does this give an error?
if [ [ $# -eq 4 ] && [ "$4" = "PREV" ] ]
then
print "yes"
fi
Error:
0403-012 A test command parameter is not valid.
Try this:
if [[ $# -eq 4 && "$4" == "PREV" ]]
then
print "yes"
fi
You can also try putting them all together like this:
if [[ $# -eq 4 && "$4" == "PREV" || $# -eq 3 && "$3" == "PREV" ]]
then
print "yes"
fi
Do you just want to check if the last argument is "PREV"? If so, you can also do something like this:
for last; do true; done
if [ "$last" == "PREV" ]
then
print "yes"
fi
'[' is not a grouping token in sh. You can do:
if [ expr ] && [ expr ]; then ...
or
if cmd && cmd; then ...
or
if { cmd && cmd; }; then ...
You can also use parentheses, but the semantics is slightly different as the tests will run in a subshell.
if ( cmd && cmd; ); then ...
Also, note that "if cmd1; then cmd2; fi" is exactly the same as "cmd1 && cmd2", so you could write:
test $# = 4 && test $4 = PREV && echo yes
but if your intention is to check that the last argument is the string PREV, you might consider:
eval test \$$# = PREV && echo yes
Try this :
if [ $# -eq 4 ] && [ "$4" = "PREV" ]
then
print "yes"
fi