I am trying to remove something based on user input using bash/sh, here is my code :
echo "remove ? [Y/n]"
read REMOVE
if [ $REMOVE != "n" ] || [ $REMOVE !="N" ];then
# ... do something ...
echo "done"
fi
the error I am getting is something like:
./run.sh: line 8: syntax error near unexpected symbol « then »
./run.sh: line 8: `if [ $REMOVE != "n" ] || [ $REMOVE !="N" ];then'
I tried to add/remove spaces many times, and I still don't understand what happens. I also don't really understand all the differences between [[ statement ]] [statement] or ((statement)).
If someone can help...
In your original problem, you need a space here
$REMOVE != "N"
In your comment response to shruti1810, it sounds like your $REMOVE variable doesn't contain what you think it contains.
Try adding
echo $REMOVE
to your script.
I typically use this construct
if [ "x$REMOVE" != "xn" ] || [ "x$REMOVE" != "xN" ]
then
# ... do something ...
echo "done"
fi
to ensure that my arguments are both valid.
Please try this:
echo "remove ? [Y/n]"
read REMOVE
if [ $REMOVE != "n" ] && [ $REMOVE != "N" ]
then
# ... do something ...
echo "done"
fi
Quote the "$REMOVE" and insert space around the "!=" -- like this;
if [ "$REMOVE" != "n" ] || [ "$REMOVE" != "N" ];then
# ... do something ...
echo "done"
fi
The problem is that is REMOVE is not set or if it is set to an empty string (like if you just press return on the 'read') you will get $REMOVE substituted to nothing and your expression would look like [ != "N" ] which will produce an unary operator expected error.
Related
In the following two lines I get this error?
What is wrong?
Debian Buster
my.sh: 101: [: !=: unexpected operator
my.sh: 103: [: !=: unexpected operator
if [ $CONTINUE != "y" ] && [ "$CONTINUE" != "n" ]; then
elif [ $CONTINUE = "n" ]; then
update
echo "\nContinue downloading? [y/n]"
read CONTINUE
# Error: Invalid argument
if [ $CONTINUE != "y" ] && [ $CONTINUE != "n" ]; then
error "Invalid argument"
elif [ $CONTINUE = "n" ]; then
echo "\nDonwload terminated!"
exit
fi
The script you’ve posted has various issues, which are highlighted by ShellCheck:
Line 1:
echo "\nContinue downloading? [y/n]"
^-- SC2028: echo may not expand escape sequences. Use printf.
Line 2:
read CONTINUE
^-- SC2162: read without -r will mangle backslashes.
Line 5:
if [ $CONTINUE != "y" ] && [ $CONTINUE != "n" ]; then
^-- SC2086: Double quote to prevent globbing and word splitting.
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
if [ "$CONTINUE" != "y" ] && [ "$CONTINUE" != "n" ]; then
Line 7:
elif [ $CONTINUE = "n" ]; then
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
elif [ "$CONTINUE" = "n" ]; then
Line 8:
echo "\nDonwload terminated!"
^-- SC2028: echo may not expand escape sequences. Use printf.
But despite these issues the script actually otherwise works as expected on Debian (Buster)’s default shell (which is dash). You might be running a non-default shell. The easiest way to solve your issue is therefore to
Declare a valid shebang line
Fix the issues highlighted above.
Which leaves us with this:
#!/bin/sh
printf "\nContinue downloading? [y/n] "
read -r CONTINUE
error() {
printf >&2 '%s\n' "$#"
exit 1
}
if [ "$CONTINUE" != y ] && [ "$CONTINUE" != n ]; then
error "Invalid argument"
elif [ "$CONTINUE" = n ]; then
printf "\nDownload terminated!\n"
exit
fi
(This also adds a definition for the undefined error call; substitute as appropriate.)
Little explanation necessary: why the hell does this doesn't work?
#!/bin/bash
ker=$1
if [ "$ker" != "iso" ] || [ "$ker" != "om" ] || [ "$ker" != "constbeta" ] ; then
printf " allowed kernels: iso, om, constbeta \n"
exit
fi
wait
echo 'anisotropy kernel: ', "$ker"
I have also tried
#!/bin/bash
ker="$1"
if [ $ker != "iso" ] || [ $ker != "om" ] || [ $ker != "constbeta" ] ; then
printf " allowed kernels: iso, om, constbeta \n"
exit
fi
wait
echo 'anisotropy kernel: ', "$ker"
I call it like this: $ ./script.sh iso
and I've even tried like this (though I think this doesn't make sense with the
scripts above): $ ./script.sh "iso"
I always get allowed kernels: iso, om, constbeta
Many thanks to those who can spot the error.
because of the logical or ||, you should use and && otherwise the condition is always true thinking to the negation string can't be equals to the three value.
You've got an irrational condition...
if [ "$ker" != "iso" ] || [ "$ker" != "om" ] || [ "$ker" != "constbeta" ] ; then
If $ker is "iso", then it is not "om" and the condition matches. If $ker is "om" then it is not "iso" and the condition matches. What you want is to OR a list of positive checks and have an "else" condition, rather than OR the negative checks.
if [ "$ker" = "iso" ] || [ "$ker" = "om" ] || [ "$ker" = "constbeta" ] ; then
: do something useful
else
: report error
fi
Or, since you're in bash, you could use a "simpler" condition:
if [[ "$ker" =~ ^(iso|om|constbeta)$ ]]; then
Though if you like you could use other constructs:
case "$ker" in
iso|om|constbeta)
: this catches our "good" values
;;
*)
echo "Error" >&2
exit 1
;;
esac
This has the possible benefit of being POSIX compliant.
Can someone tell me why this script isnt working? I'm getting
./FileDirTest.sh: line 10: [: missing `]'
./FileDirTest.sh: line 10: n: command not found
./FileDirTest.sh: line 13: [: missing `]'
./FileDirTest.sh: line 13: n: command not found
Here is my script.
if [ -d "$PASSED1" ]
then echo "Do you want to execute whole directory?(Y/N)"
read answer
if [ "$answer" == "y" || "$answer" == "Y" ] ;
then echo "Execute"
fi
if [ "$answer" == "n" || "$answer" == "N" ] ;
then echo "No"
exit 1
fi
fi
Im sure it is something simple. I new to all of this.
|| is not a valid operator for the [ command; you can only use it to join two distinct [ commands:
if [ "$answer" = "y" ] || [ "$answer" = "Y" ];
You can, however, use || inside bash's conditional command:
if [[ "$answer" = "y" || "$answer" = "Y" ]];
The first of the two errors occurs because ||, being a special shell operator, indicates that the previous command is complete, but [ requires ] be given as the final argument. The second error occurs because the value of $answer, immediately following ||, is taken as the name of the command to run.
In addition to #Chepner's answer, you can also use, bash -o operator,
if [ "$answer" == "y" -o "$answer" == "Y" ]; then
echo "Execute"
else
echo "No"
exit 1
fi
I have the following shell script.
if [ "$group" == "First*" ]]
then
OWNER_EMAIL=first-logs#ginger.com
elif [ "$group" == "Second*" ]]
then
OWNER_EMAIL=second-team#ginger.com
fi
It does not throw any error , but does not execute the if statement properly if $group contains a First or a Second inside. Can any one tell me where I am going wrong.
You can also consider a case statement for efficiency:
case "$group" in
First*)
OWNER_EMAIL=first-logs#ginger.com
;;
Second*)
OWNER_EMAIL=second-team#ginger.com
;;
esac
You can add *) ... ;; as well for default action.
Remove the quotes "" and it is done
if [ "$group" == First* ]
then
OWNER_EMAIL=first-logs#ginger.com
elif [ "$group" == Second* ]
then
OWNER_EMAIL=second-team#ginger.com
fi
When we use double quotes the wildcard character are not retained ... the check condition is looking for a exact "First*" and "Second*" match .
change your code in following way
if [[ "$group" == First* ]]
then
OWNER_EMAIL=first-logs#ginger.com
elif [[ "$group" == Second* ]]
then
OWNER_EMAIL=second-team#ginger.com
fi
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"