Problems with the control design [duplicate] - linux

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 3 months ago.
Good evening (or day. Whichever)! I ran into a problem while writing a bash script. I have the code
#!/bin/bash
echo "Available options:"
echo "1. text"
echo "2. exit"
read var1
echo
if [[$var -ge 0]]; then
echo "hello world"
elif [[$var -ge 1]]; then
echo "good bye"
else
echo "error"
fi
and all the time it puts the emphasis on the operator
./proba3.sh: line 9: [[: command not found
./proba3.sh: line 11: [[: command not found
I tried many variations of the branching operation, but still get the same error. I will be very glad for advice or hints on how to fix this error. Thanks in advance

You need spaces inside the brackets.
Also you misspelled the variable name.
Finally, you should probably test for equality not ge
Fixed:
#!/bin/bash
echo "Available options:"
echo "1. text"
echo "2. exit"
read var
echo
if [[ $var -eq 1 ]]; then
echo "hello world"
elif [[ $var -eq 2 ]]; then
echo "good bye"
else
echo "error"
fi

Related

Yes or No in Bash Script

I have a set of 100 questions. My requirement is when a user enter "yes", then question 1 should appear. If not, directly it go to question 2. Like that it should go on till 100 questions. Any lead would be appreciated.
This is what I tried, but it is failing.
#!/bin/bash
echo "Execute question1 "
select result in Yes No
do
echo "How to see apache config file"
exit
done
echo "execute question2"
select result in Yes No Cancel
do
echo "Command for listing processes"
exit
done
Thanks in advance
Here is a way to do this with an array.
#!/bin/bash
questions=(
"How to see apache config file"
"Command for listing processes"
"My hovercraft is full of eels"
)
for((q=0; q<${#questions[#]}; q++)); do
echo "Execute question $q?"
select result in Yes No; do
case $result in
Yes)
echo "${questions[q]}";;
esac
break
done
done
Using select for this seems rather clumsy, though. Perhaps just replace it with
read -p "Execute question $q? " -r result
case $result in
[Yy]*) echo "${questions[q]}";;
esac
Having just a list of questions still seems weird. With Bash 5+ you could have an associative array, or you could have a parallel array with the same indices with answers to the questions. But keeping each question and answer pair together in the source would make the most sense. Maybe loop over questions and answers and assign every other one to an answers array, and only increment the index when you have read a pair?
pairs=(
"How to see Apache config file"
"cat /etc/httpd.conf"
"Command for listing processes"
"ps"
"My hovercraft is full of what?"
"eels"
)
questions=()
answers=()
for((i=0; i<=${#pairs[#]}/2; ++i)); do
questions+=("${pairs[i*2]}")
answers+=("${pairs[1+i*2]}")
done
This ends up with two copies of everything, so if you are really strapped for memory, maybe refactor to just a for loop over the strings and get rid of the pairs array which is only useful during initialization.
Use an array of questions and loop over it, like this:
#!/bin/bash
n=1
questions=(
'How to see apache config file'
'Command for listing processes'
)
check_user_input(){
read -p "y/n " input
case $input in
[Yy]*) return 0;;
[Nn]*) return 1;;
*) check_user_input;;
esac
}
for question in "${questions[#]}"; {
echo "Execute question $n"
check_user_input && echo "$question"
((n++))
}
Here is a straight forward example. Play with it.
#!/bin/bash
echo "Type 'y' for yes, 'n' to skip or 'q' to quit and press Enter!"
for((i=1; i < 101; ++i)); do
echo 'Execute question '$i
while read user_input; do
if [[ "$user_input" = 'q' ]]; then
break 2
elif [[ "$user_input" = 'n' ]]; then
break
elif [[ $i -eq 1 ]]; then
echo 'How to see apache config file?'
break 2 # Change from "break 2" to "break" for the next question.
elif [[ $i -eq 2 ]]; then
echo 'Command for listing processes.'
break 2 # Change from "break 2" to "break" for the next question.
else
echo "Wrong input: $user_input"
echo "Type 'y' for yes, 'n' to skip or 'q' to quit and press Enter!"
fi
done
done
echo 'Finished'

Why does my check for uppercase always result in true even when it shouldn't? [duplicate]

This question already has an answer here:
Weird behavior of BASH glob/regex ranges
(1 answer)
Closed 4 years ago.
I'm writing a script to check a password if it has upper case or not, but it always shows that it has upper case.
I tried to use
if [[ $password =~ [A-Z] ]]; then
echo "Contains Upper Case"
but it always prints that.
This is my script:
read -p "Enter Password: " password
if [ ${#password} -lt 8 ]; then
echo "TOO SHORT , MAN! "
fi
if [[ $password =~ [A-Z] ]]; then
echo "Contains Upper Case"
fi
Do not use [A-Z]. It works only in some language settings / locales (the ones where ordering looks like ABCD...Zabcd...z, intead of like AaBb...Zz).
For your code to work everywhere, use [[:upper:]] instead.
#!/usr/bin/env bash
[ -n "$BASH_VERSION" ] || { echo "ERROR: Shell is not bash" >&2; exit 1; }
if [[ $password =~ [[:upper:]] ]]; then
echo "Contains at least one upper-case character"
else
echo "Does not contain one or more upper-case characters"
fi

Shell Script Showing Error Message When Redirecting Echo Within If-Else Statements

I am trying to redirect the output to a file within if-else statements but it is not working with me. Here's what I am doing
$1=1
output="/home/file.txt"
if [[ $1 -gt 5 ]]
then
echo "$1 is greater than 5" > $output #this is working with me
else
echo "$1 is not greater than 5" > $output #this is giving me "ambiguous redirect"
fi
Any idea what the issue may be? I tried puting $output between double quotes, but I got a different error message:
if [[ $1 -gt 5 ]]
then
echo "$1 is greater than 5" > "$output" #this is working with me
else
echo "$1 is not greater than 5" > "$output" #this is giving me "No such file or directory"
fi
First of all never use $1 till $9 as variable in your script (also never declare variable with $). These are Unix/Linux system variable and these variable use by Unix/Linux to store the command line parameters:
For example:-
yourshellscript.sh hello word!
echo $1" "$2 # this will print hello world!
I have modified your script which will work for you
#!/bin/bash
#always put this line at the top of your shell script this indicate in
#which shell this script should run in this case it is bash shell. This is
#very important because each shall has different syntax for if, while
#condition and numeric expression.
NUMBER=1
output="/home/file.txt"
if [ $NUMBER -gt 5 ]
then
echo "$NUMBER is greater than 5" > $output #this is working with me
else
echo "$NUMBER is not greater than 5" > $output #this is giving me "ambiguous redirect"
fi
Also you can enter a number from consul like below:-
NUMBER=1
read -p "Enter a Number : " NUMBER
output="/home/file.txt"
if [ $NUMBER -gt 5 ]
then
echo "$NUMBER is greater than 5" > $output #this is working with me
else
echo "$NUMBER is not greater than 5" > $output #this is giving me "ambiguous redirect"
fi

if statement not working in Bash script [duplicate]

This question already has answers here:
Syntax error near unexpected token 'then'
(2 answers)
Closed 6 years ago.
I can't understand why this simple if statement to check whether a string is empty is not working. It's giving me:
syntax error near unexpected token `then'
#!/bin/bash
str="Hello World!"
if[ ! -z "$str"]; then
echo "str is not empty"
fi
I tried it on my PC and an online editor as well but it shows the same issue. Any idea?
#!/bin/bash
str="Hello World!"
if [ ! -z "$str" ]; then
echo "str is not empty"
fi
Maybe,
insert space after "if" statement.
and, before "]".
[[ ]] is better than [ ] for tests:
#!/bin/bash
str="Hello World!"
if [[ ! -z $str ]]; then
echo "str is not empty"
fi
Shorter form:
#!/bin/bash
str="Hello World!"
[[ ! -z $str ]] && echo "str is not empty"

Bash if string = this or that [duplicate]

This question already has answers here:
How do I prompt for Yes/No/Cancel input in a Linux shell script?
(37 answers)
Closed 2 years ago.
Trying to write a script which will read what a user has imput... I know it's basic but im stuck on the first if..
echo "Please enter yes or no (y/n)?"
read string
if [ $string = "y" -o "n" ]
then
echo "User selected $string"
else
echo "You didn't enter y/n !!!"
fi
I would like it to be if [ $backup = "y" or "n" ]
Any ideas?
Use this syntax in bash :
if [ "a string" = "another one" ] ; then
# Whatever
fi
For multiple conditional statements such as OR, use:
if [ "a string" = "another one" ] || [ "$foo" = "bar" ] ; then
# Whatever
fi
bash also supports the non-standard [[ ... ]] expression, which can process a compound comparison using a single command, rather than 2 [ commands:
if [[ "a string" = "another one" || $foo = "bar" ]]; then
# Whatever
fi
Not the question you actually asked, but... You told the user to enter "yes" or "no" but only test for y or n - sure, you gave them a hint but users are hint-resistant. So maybe a looser test is in order:
echo "Please enter yes or no (y/n)"
read string
case "$string" in
[yY]* | [nN]*) echo "User entered $string" ;;
*) echo "I don't understand '$string'" ;;
esac
That will recognize any variation that begins with Y or N - usually that's good enough, but you could tighten up the tests. Also, since you'll probably want to do something different with a yes or no response you can expand the case (I've also tightened the tests in this one):
case "$string" in
[yY] | [yY][eE][sS]) echo "Here's where you process yes" ;;
[nN] | [nN][oO]) echo "And here you deal with no" ;;
*) echo "I don't understand '$string'" ;;
esac
You could do this with if statements but I find case more readable when more than two alternatives are possible and the test is appropriate to case syntax.
You can also try:
echo "Please enter yes or no (y/n)?"
read string
if [[ "$string" =~ ^(y|n)$ ]]
then
echo "User selected $string"
else
echo "You didn't enter y/n !!!"
fi
I nice solution is would be with case, which is easier to extend if you want to make your input more complex
case $string in
y|n) echo "User selected $string"
;;
*) echo "You didn't enter y/n !!!"
;;
esac
From there you can easily modify it to accept Uppercase or whatever:
case $string in
y|Y) echo "yes, Sir!"
;;
n|N) echo "No, can't do"
;;
*) echo "Say what?"
;;
esac
Check case statements for more info.

Resources