I'm creating a shell script to automatically do sudo apt update/upgrade/autoremove/autoclean (first bash script of my life), everything works but the yes or no section
Here's my code:
#!/bin/bash
echo "Updating and upgrading system components"
sudo apt update
sudo apt upgrade
echo "Starting cleaning and removing unnecessary files"
sudo apt autoremove
sudo apt autoclean
echo "Do you want to check if a new distribution update is available? Y/N"
read -p "Check system distribution updates?" answer
if ["$answer" == "Y" || "$answer" == "Yes" || "$answer" == "y" || "$answer" == "yes"]
then
sudo do-release-upgrade
else
exit
fi
After answering one of these option shell starts printing in loop "==Yes"
Any idea?
[ needs to be separated by space from its arguments. ["$answer" gets parsed as a single command with two arguments, == and Y. Such a command doesn't exist, so it fails, and || tries the next command. The next command is yes: it's a command that prints its arguments infinitely. The arguments in this case are == and Yes.
The correct way to write the condition is
if [ "$answer" == "Y" ] || [ "$answer" == "Yes" ] || [ "$answer" == "y" ] || [ "$answer" == "yes" ]
or
if [ "$answer" == "Y" -o "$answer" == "Yes" -o "$answer" == "y" -o "$answer" == "yes" ]
or, if you're using bash
if [[ $answer == Y || $answer == Yes || $answer == y || $answer == yes ]]
You can also use parameter expansion to lowercase the answer (but it includes yEs etc. among the accepted answers)
if [[ ${answer,} == y || ${answer,,} == yes ]]
Or you can use a regex with the =~ operator
if [[ ${answer,,} =~ ^y(es)?$ ]]
Under shopt -s extglob, you can use a pattern to match both the cases in one expression:
if [[ ${answer,,} == y?(es) ]]
Related
I have the following script:
#!/usr/bin/bash
arch=`uname -p`
if [[ "$arch" == "x86_64" ]]
then
echo "Yes"
else
echo "No"
fi
Is there a way to write this as a short one-liner on the command prompt, $ instead of having it as a script. Something like:
$ test uname -p == "x86_64" ? "Yes" : "No"
Though I'm not sure of the ternary usage (?) in bash.
You could use the following, where the && part would run if the statement evaluates to True, and || would run run otherwise:
[ "`uname -p`" = "x86_64" ] && echo "Yes" || echo "No"
Here is my code
#! /bin/bash
read var
if [ $var="Y" -o $var="y" ]
then
echo "YES"
else
echo "NO"
fi
I want to print YES if the user presses y or Y, otherwise I want to print NO. Why doesn't this code work?
Basically, your Condition is wrong. Quote your variables and leave spaces between operators (like shellter wrote). So it should look like:
#! /bin/bash
read var
if [ "$var" = "Y" ] || [ "$var" = "y" ]
then
echo "YES"
else
echo "NO"
fi
Edit: for POSIX ccompatibility
Replaced == with = - see comments
Replaced -o syntax with || syntax - see comments
With Bash, you can also use regular expression in your test with the =~ operator:
read var
[[ "$var" =~ [Yy] ]] && echo "YES" || echo "NO"
Or as Benjamin W. mentionned, simply use character range with the == operator:
read var
[[ "$var" == [Yy] ]] && echo "YES" || echo "NO"
There is minor syntax error in your code.
Correction : There should be a white space between operators and variables
read var
if [ $var = "Y" -o $var = "y" ]
then
echo "YES"
else
echo "NO"
fi
Try the above bash script.
Hope it would work fine.
Happy Coding!
If all you require is a upper/lowercase comparison, use the ,, operator on the variable being compared ( note the ${var,,} ):
#!/bin/bash
read var
if [ ${var,,} = "y" ]
then
echo "YES"
else
echo "NO"
fi
or more succinctly:
#!/bin/bash
read var
[ ${var,,} = 'y' ] && echo 'YES' || echo 'NO'
or the way I might actually do it:
#!/bin/bash
read var
[[ "${var,,}" == 'y' ]] && echo 'YES' || echo 'NO'
Below is the code that I tried.
#! /bin/bash
read -p "Are you Sure?(Y/N) " answer
if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
echo "Do your stuff."
else
echo "Do your other stuff"
fi
Add whitespace around '=' and your code will run fine.
#! /bin/bash
read var
if [ $var = "Y" -o $var = "y" ]
then
echo "YES"
else
echo "NO"
fi
Try this code.
#! /bin/bash
read var
echo -e "YES\nNO\n" | grep -i $var
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've written below code, but it won't work for SPACE,special symbols etc.
I want my script to exit if any key pressed on keyboard apart from Y/y.
It should handle SPACEBAR,special symbols
echo "enter y, any other key to exit "
read input
if [ $input != "Y" -o $input = "y" ]; then
echo "Exiting"
fi
if [ $input == "Y" -o $input == "y" ]; then
echo "Working"
fi
See http://wiki.bash-hackers.org/commands/builtin/read?s[]=read
Normally you always want to use the -r flag. -n 1 tells read to only read 1 character.
asksure() {
echo -n "Are you sure (Y/N)? "
while read -r -n 1 -s answer; do
if [[ $answer = [YyNn] ]]; then
[[ $answer = [Yy] ]] && retval=0
[[ $answer = [Nn] ]] && retval=1
break
fi
done
echo # just a final linefeed, optics...
return $retval
}
### using it
if asksure; then
echo "Okay, performing rm -rf / then, master...."
else
echo "Pfff..."
fi
First, you need to quote the parameter expansions to make sure certain inputs are not removed altogether during word splitting and quote removal.
You are using the wrong operator. No matter what key you type, one of not Y and not y will be true. For example, "Y" != "y". You want to use and instead of or.
if [ "$input" != "Y" ] && [ "$input" != "y" ]; then
The boolean operators -o and -a are no longer recommended, due to ambiguities than can arise from their use. Use separate test commands joined by || and && (respectively) instead.
You need to put $input in quotes, so the statement parses properly. If your response is a space, what the script sees is
if [ != "Y" -o != "y" ]; then
Which it obviously can't parse properly.
Use
if [ "$input" != "Y" -o "$input" = "y" ]; then
and you should be OK.
By the way, you don't actually exit if the condition is met. Add a return after the echo "Exiting" line.
I'm having an issue getting a a simple y/n question to work. Consider the following code:
echo "Hi there"
read ans
if [[ $ans != "y" || $ans != "Y" || $ans != "YES" || $ans != "yes" ]]; then
echo "Foo"
exit 0
fi
I've looked at – I would argue – some of the more informative answers on StackOverflow for advice: Simple logical operators in Bash
I've tried all different types of variations such as:
if [[ ($ans != "y" || $ans != "Y" || $ans != "YES" || $ans != "yes") ]]; then
echo "Foo"
exit 0
fi
if [[ ($ans != "y*" || $ans != "Y*" || $ans != "YES*" || $ans != "yes*") ]]; then
echo "Foo"
exit 0
fi
if [[ ($ans != "y") || ($ans != "Y") || ($ans != "YES") || ($ans != "yes") ]]; then
echo "Foo"
exit 0
fi
Regardless of why I type in any of these cases, it automatically fails and I'm not sure why. If anyone has a better way to handle y/n answers then please let me know! Ideally I would like to use pattern matching (like I might do with Perl) but I'm not entirely sure the best way/most efficient way to accomplish a simple y/n question.
You need to use && instead of ||. As it stands you're saying if it's not equal to any of those possibilities, then execute the "then" block. You mean to say if it's not equal to all of them, then execute the "then" block. That requires &&.
You can use:
echo "Hi there"
read ans
case "$ans" in
y|Y|YES|yes)
;;
*)
echo "Foo"
exit 0
;;
esac
The logic needs to be adjusted:
echo "Hi there"
read ans
if ! [[ "$ans" == "y" || "$ans" == "Y" || "$ans" == "YES" || "$ans" == "yes" ]]; then
echo "Foo" # User answered no
exit 0
fi
The will echo "Foo" only if the answer was not one of "y", "Y" or "YES". By contrast, consider the original logic:
[[ $ans != "y" || $ans != "Y" || $ans != "YES" || $ans != "yes" ]]
At least one of these tests will be true regardless of what the user's answer is.
Using the case statement
You might consider using the case statement to analyze the user's answer:
read -p "Hi there: " ans
case "$ans" in
[yY]*) ;;
[nN]*) echo "Foo" ; exit 0 ;;
*) echo "You were supposed to answer yes or no" ;;
esac
Try read ans, not read $ans.