If statement goes else every time - bash - bash

I am very new here, so I apologize for any my mistakes, and I am sorry for my lack of knowledge (I'm just beginner).
So here it is, i am doing little script in bash with li and I have if statement, here it is
#!/bin/bash
something=$(whiptail --inputbox "Enter some text" 10 30 3>&1 1>&2 2>&3)
if [ $something ?? 'you' ];
then
echo "$something"
else
echo "nope"
fi
To be specific what i want from it - I enter some word/sentence/whatever to whiptail, and if it contains some of of you string then prints it, but every times it goes else ;_;.Please help.
EDIT now it works, thanks but I need to check if string contains word.
if [[ $string =~ .*My.* ]]
doesn't seem to work

I don't get it at all, losing hope and searching the web i've encontered on
#!/bin/bash
OPTION=$(whiptail –title “Menu Dialog” –menu “Choose your option” 15 60 4 \ “1” “Grilled ham” \ “2” “Swiss Cheese” \ “3” “Charcoal cooked Chicken thighs” \ “4” “Baked potatos” 3>&1 1>&2 2>&3)
exitstatus=$?
if [ $exitstatus = 0 ];
then echo “Your chosen option:” $OPTION
else echo “You chose Cancel.”
fi
And I've just pasted this script to check how it works and modify it, it isn't mine script and it supposed to work, but it says “You chose Cancel.”

What you may be looking for are the string comparison operators like == or !=. For example,
if [ "$something" == "you" ]; then
echo "$something"
else
echo "nope"
fi
If $something equals you then echo $something; else echo nope.
Or, as David C.Rankin mentioned in his comment you can check the string variable to prove whether a string is empty or not. For example,
if [ -z "$something"] ;then
String is empty
if [ -n "$something" ]; then
String is non-empty
For more information on this check the TEST manual page.

Related

While loop in Bash not running

I'm pretty new with Bash scripting and am having trouble getting my 'while' loop to run. When I echo keywords, a whole list of words prints and then when I echo length, it prints 124. I believe I'm using the while loop and condition correctly, so I can't figure out what I'm doing wrong. Any thoughts?
keywords=$1
length=${#keywords}
echo "$keywords"
echo "$length"
if [ -z "$keywords" ]; then
while [ $length -gt 100 ]; do
echo "$keywords"
echo "$length"
keywords="${keywords%,*}"
length=${#keywords}
done
fi
echo $keywords
The problem is here:
[ -z "$keywords" ]
-z is true if its argument is an empty string. Something of length 124 is definitely far from empty. You probably meant -n.
Next time, please also include the input in the question so we can reproduce the problem.

Shell Script Syntax Error

At the moment I am working on a blackjack game using shell script. I have most of the script working with functions however the method I am using to find out if the player/computer goes bust doesn't seem to work. Could anyone point me in the right direction. (I am new to shell script.) When running it it will throw syntax errors around the lines that begin elif and sometimes if. It also prints all of the 'echo' outputs in bustConfirm instead of only the one that is true.
Also yes, one of my functions is called bustCheck.
bustConfirm(){
bust='bust'
under='under'
if [ $userBust -eq $bust -a $systemBust -eq $bust ]
then
echo "You both went bust! Be more careful!"
endGameRepeat
elif [ $userBust -eq $bust -a $systemBust -eq $under ]
echo $userName "went bust! Congratulations" $systemName"!"
endGameRepeat
elif [ $userBust -eq $under -a $systemBust -eq $bust ]
then
echo $systemName "went bust! Congratulations" $userName"!"
endGameRepeat
else
echo "Nobody went bust! Well played!"
endGameScores
fi
}
bustCheck(){
if [ "$userScore" -gt 21 ]
then
echo $userName "is bust!"
userBust='bust'
else
userBust='under'
fi
if [ "$systemScore" -gt 21 ]
then
echo $systemName "is bust!"
systemBust='bust'
else
systemBust='under'
fi
bustConfirm
}
The idea is that I wanted to use an && in the bustConfirm function and then an || to get the player is bust or system is bust result if only one of them was bust.
Also just a pointer but in the bustCheck I am seeing userBust and systemBust to contain the words bust or under. I created the variables bust and under for the bustConfirm function.
systemScore, userScore, systemName and userName are set before when the script is running.
Hope I've given enough detail and formatted it properly, first proper post so I apologize if not!
Taking a quick look, I see that the first if statement doesn't have a space after the opening square bracket.
I also recommend you put quotes around your variable names in if statements. This is due to the way shell actually works. The bash shell is extremely intelligent, and before your program has a chance to do anything, it grabs the line, does its magic, and then presents the line to the processor.
For example:
foo=""
if [ $foo = "" ]
then
echo "Foo is blank"
fi
Seems simple enough. However, what happens is that your shell will grab the line, substitute the value of $foo for the string "$foo", and then execute the line. Since $foo is blank, your if statement will become:
if [ = "" ] # That's not right!
then
echo "Foo is blank"
fi
By using quotes, this:
foo=""
if [ "$foo" = "" ]
then
echo "Foo is blank"
fi
becomes:
foo=""
if [ "" = "" ]
then
echo "Foo is blank"
fi
And that is valid. Another thing you can do is use the new test format that uses double square brackets:
foo=""
if [[ $foo = "" ]]
then
echo "Foo is blank"
fi
This will always work even without the extra quotes, and is now recommended unless you have to have your program compatible with the original Bourne shell syntax.
One more thing you can do in debugging your shell script is to use set -xv which turns on verbose debugging. Each statement, before it is executed will be printed, then it will print again after the shell fills in variables, patterns, etc., and then execute. It's a great way to debug your program. Just put set -xv on the line before you want this verbose debugging mode and use set +xv to turn it off. (Yes, the - turns it on and + turns it off.)
Thanks alot David, great answer, could you also tell me what the best way to get the && or equivalent of it within this as I need to find out if they are both bust, or just one etc
As already mentioned in a comment, you can use either one of these two forms:
if [ "$foo" = "bar" ] && [ "$bar" = "foo" ]
or
if [[ $foo = "bar" && $bar = "foo" ]]

shell script if else loop not working

Given the following programme which reads in user input twice
function search_grep
{
if [ "$2" == "" ];then
for x in "${title[#]}"
do
value=$(echo $x | grep "$1")
if [ "$value" != "" ];then
echo "$value"
fi
done
elif [ "$1" == "" ];then
hello="123"
echo "$hello"
fi
}
echo -n "Enter title : "
read book_title
echo -n "Enter author : "
read author
title=(CatchMe HappyDay)
search_grep $book_title $author
it works as expected when i enter followed by HappyDay HOWEVER
When i enter foo followed by , I would expect console output to be
123
instead I am getting
Can someone explain to me , the programme is not executing the second elif loop though second input is
In both of your cases cases, the following:
search_grep $book_title $author
expands to a call with a single argument. Hence, the "then" clause is activated. The reason is that an unquoted argument consisting of whitespace expands to nothing and disappears. That is the way of bash.
If you want to pass search_grep two arguments, then you need to quote the variables:
search_grep "$book_title" "$author"
As shown here, you might try using = instead of ==
Or for an empty string comparison try -z

bash - if return code >=1 re run script, start at the beginning

I have a bash script that prints a heading and tests for a value of "Y" or "N".
When someone enters text that does not equal "Y" or "N", I would like to send them back to the beginning of the script, so it prints the heading and the question again.
I know you can do this with goto but I was wondering if there's a different way because I hear many individuals say you should not use goto or that it is deprecated. Whether true or not, I'd like to see if anyone else has a way to solve this problem.
Thanks in advance.
You could implement it in a loop:
while [ !$exit_loop ]
do
echo "enter choice - "
read -n 1 input
case "$input" in
y|Y) $exit_loop = 1;;
n|N) $exit_loop = 1;;
*) echo "invalid choice";;
esac
done
Personally I find no difference between using a goto/loop or any other means. I'd always say to use what is most suitable for the situation - for yours, I'd use a goto.
e.g. If you have multiple indentations spanning lots of lines, and you need to jump back to the start of a function, I'd use a goto - it's a lot easier to understand in its context.
As a direct answer to your question, you can use exec to replace the current process with another process, or, as the case may be, another fresh copy of the current process.
read -p "Yes? Or no? " yn
case $yn in
[YyNn]) ;;
*) exec "$0" "$#"
esac
If you want a more structured approach, you can use a while or until loop.
Example (slightly simplified) using #Michael's suggestion follows. The exit condition is in the while loop, but the user can also do an intermediary action to decide which action to take:
while [[ ! "${action-}" =~ ^[SsRr]$ ]]
do
echo "What do you want to do?"
read -n 1 -p $'[d]iff, [s]kip, [S]kip all, [r]eplace, [R]eplace all: \n' action
if [[ "${action-}" =~ ^[Dd]$ ]]
then
diff "$target_path" "$source_path"
fi
done
echo "Hello User, are you ready to learn some Linux?"
while true; do
echo "Please enter y/n:"
read a
bfunc() {
if [ "$a" == "y" ]
then
echo "That is great, lets get started!"
echo "This Script is under construction, functionality coming soon"
exit 0
elif [ "$a" == "n" ]
then
echo "That is too bad, see you next time!"
echo "You are now exiting the script"
exit 0
else [ "$a" != "y||n" ]
echo "Please only enter y or n!"
fi
}
bfunc
done

bash: Can't get simple 'if' to work

I don't understand why this simple read doesn't work. Mind you, I am VERY new to bash. :)
#!/bin/bash
echo -n "Project Name: "
read PROJECT_NAME
if [ -n "$PROJECT_NAME" ]; then
echo "You must provide a project name."
exit 2
fi
-- snip --
When this executes, it asks for the project name. After I press enter, I get "You must provide a project name." and then the scripts exists instead of continuing.
What am I doing wrong?
Thanks
Eric
You want [ -z "$PROJECT_NAME" ], not -n:
From man test:
-n STRING
the length of STRING is nonzero
...
-z STRING
the length of STRING is zero
to avoid confusion from -n or -z , you can just use case/esac to compare strings
case "$PROJECT_NAME" in
"" ) echo "No";;
*) echo "Have";;
esac

Resources