LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-06-2012, 12:40 PM   #1
da_667
LQ Newbie
 
Registered: Aug 2012
Posts: 6

Rep: Reputation: Disabled
Bash script not performing a check properly


Hello,

I'm trying to throw together a bash script on Ubuntu Server 12.04. One of the sub-portions of the script is verifying wget exists in /usr/bin. If it doesn't exist, my script offers to install it via apt-get.

Here's a potion of my script that is giving me problems. For ease of debugging, I made it its own shell script:

Code:
#!/bin/sh
echo "Finding wget..."
        if [ $(ls -al /usr/bin/ | grep wget | cut -f16 -d " ") != "wget" ]
                then
                        echo "wget not found. Install wget?"
                        read wget_install
                                if $wget_install = ["yes"] || ["y"]
                                        then
                                                echo "installing wget. \n"
                                                apt-get install -y wget
                                        else
                                        echo "Either you have selected no, or I didn't understand what you entered. wget is required to continue. after the installer is finished, you may remove wget at your discretion."
                                fi
                else
                        echo "found wget."
        fi
exit 0
when this script is ran, I get

Code:
root@Gatekeeper:~# sh wgetcheck.sh 
Finding wget...
wgetcheck.sh: 3: [: !=: unexpected operator
found wget.
So the unexpected operator error leads me to believe it's not doing the logic check I want it to do. I've used the same programming logic to do other system checks (e.g. network connectivity, which user are we running as, etc.) and there's no problem, so I'm a little stumped. Thanks in advance for any assistance you provide.
 
Old 08-06-2012, 12:56 PM   #2
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,568

Rep: Reputation: 411Reputation: 411Reputation: 411Reputation: 411Reputation: 411
Try switching it to :

Code:
if [ -z $(ls -al /usr/bin/ | grep wget | cut -f16 -d " ") ]
You could also do it this way:

Code:
/usr/bin/which wget

if [ $? -ne 0 ]
then
                        echo "wget not found. Install wget?"
                        read wget_install
                                if $wget_install = ["yes"] || ["y"]
                                        then
                                                echo "installing wget. \n"
                                                apt-get install -y wget
                                        else
                                        echo "Either you have selected no, or I didn't understand what you entered. wget is required to continue. after the installer is finished, you may remove wget at your discretion."
                                fi
                else
                        echo "found wget."
        fi
Using exit codes is more reliable than doing a cut statement.
 
1 members found this post helpful.
Old 08-06-2012, 12:58 PM   #3
whizje
Member
 
Registered: Sep 2008
Location: The Netherlands
Distribution: Slackware64 current
Posts: 583

Rep: Reputation: 129Reputation: 129
It is bad practice relying on ls better use if file exist
Code:
if [ -e "/usr/bin/wget" ]; then echo "hurrah"; fi
 
Old 08-06-2012, 01:01 PM   #4
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,568

Rep: Reputation: 411Reputation: 411Reputation: 411Reputation: 411Reputation: 411
Quote:
Originally Posted by whizje View Post
It is bad practice relying on ls better use if file exist
Code:
if [ -e "/usr/bin/wget" ]; then echo "hurrah"; fi
I also agree with this solution, using exit codes or a hard test statement such as this against the file is the best coding practice, using cut, grep etc.. causes some inconsistent results.
 
1 members found this post helpful.
Old 08-06-2012, 01:35 PM   #5
da_667
LQ Newbie
 
Registered: Aug 2012
Posts: 6

Original Poster
Rep: Reputation: Disabled
I've tried utilizing both methods (the -z and utilizing exit code checks) and they both work, now I run into a problem where the read statement works, but the portion where the script is looking for y or yes to indicate yes is not working. For readability, let me post version 2:

Code:
#!/bin/sh
/usr/bin/which wget
if [ $? -ne 0 ]
then
        echo "wget not found. Install wget?"
        read  wget_install
                if $wget_install = ["yes"] || ["y"]
                        then
                                echo "installing wget. \n"
                                apt-get install -y wget
                        else
                        echo "Either you selected no or I didn't understand. Wget is required to continue."
                        exit 1
                fi
        else
                echo "found wget."
fi

exit 0
Identical to Kustom42's version with exit codes for verification. Now when I run the script, the y || yes isn't being parsed correctly. Either that or I'm borking this pretty badly again. Here are outputs I get:

if the word yes is entered:

I get an infinite loop where the text "= [yes]" is returned repeatedly.

if I enter y, I get this:

Code:
root@Gatekeeper:~# sh wgetcheckv2.sh 
wget not found. Install wget?
y
wgetcheckv2.sh: 7: wgetcheckv2.sh: y: not found
wgetcheckv2.sh: 7: wgetcheckv2.sh: [y]: not found
Either you selected no or I didn't understand. Wget is required to continue.
root@Gatekeeper:~#
if I enter any other input, I get this:

Code:
root@Gatekeeper:~# sh wgetcheckv2.sh 
wget not found. Install wget?
n
wgetcheckv2.sh: 7: wgetcheckv2.sh: n: not found
wgetcheckv2.sh: 7: wgetcheckv2.sh: [y]: not found
Either you selected no or I didn't understand. Wget is required to continue.
root@Gatekeeper:~#
Thoughts? thanks for the help thus far.

Last edited by da_667; 08-06-2012 at 01:37 PM. Reason: edit: cleaned up tags for clarity.
 
Old 08-06-2012, 01:46 PM   #6
suicidaleggroll
Senior Member
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 2,813

Rep: Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996
You can't do tests that way.

Break it out of the script and just run it from the command line. Does this work?
Code:
if y = ["yes"] || ["y"]; then echo 1; fi
?

If not, modify it until it does, then put the corrected version back into the script. The nice thing about scripting languages is you don't need the entire code to test one line. You can test that if statement by itself from the command line until it works, then insert the working version into the script.
 
Old 08-06-2012, 01:58 PM   #7
Roken
Member
 
Registered: Oct 2011
Location: Bolton, UK
Distribution: Arch local, Debian on VPS
Posts: 252

Rep: Reputation: 40
Alternatively, use case:

Code:
#!/bin/sh
/usr/bin/which wget
if [ $? -ne 0 ]; then
	echo "wget not found. Install wget?"
	read  wget_install
	case $wget_install in
	[yY] | [yY][Ee][Ss])
		echo "installing wget. \n"
		apt-get install -y wget
		;;
	*)
		echo "Either you selected no or I didn't understand. Wget is required to continue"
		exit 1
		;;
	esac
else
	echo "found wget."
fi
exit 0
 
1 members found this post helpful.
Old 08-06-2012, 02:24 PM   #8
da_667
LQ Newbie
 
Registered: Aug 2012
Posts: 6

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Roken View Post
Alternatively, use case:

Code:
#!/bin/sh
/usr/bin/which wget
if [ $? -ne 0 ]; then
	echo "wget not found. Install wget?"
	read  wget_install
	case $wget_install in
	[yY] | [yY][Ee][Ss])
		echo "installing wget. \n"
		apt-get install -y wget
		;;
	*)
		echo "Either you selected no or I didn't understand. Wget is required to continue"
		exit 1
		;;
	esac
else
	echo "found wget."
fi
exit 0
You know,

I didn't even think to use a case statement. thank you very much for this. I ended up getting the or statement to evaluate, then I ran into a snag where the script would not take no for an answer. This solves the problem very well.

Thanks again!
 
Old 08-06-2012, 02:29 PM   #9
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,568

Rep: Reputation: 411Reputation: 411Reputation: 411Reputation: 411Reputation: 411
Just an informational follow up, this could have been done pretty easily with the "select" function as well:

http://tldp.org/LDP/Bash-Beginners-G...ect_09_06.html
 
1 members found this post helpful.
Old 08-06-2012, 02:34 PM   #10
da_667
LQ Newbie
 
Registered: Aug 2012
Posts: 6

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Kustom42 View Post
Just an informational follow up, this could have been done pretty easily with the "select" function as well:

http://tldp.org/LDP/Bash-Beginners-G...ect_09_06.html
Duly noted...

thanks again!
 
Old 08-06-2012, 02:40 PM   #11
suicidaleggroll
Senior Member
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 2,813

Rep: Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996
FYI - a working if could have looked like:
Code:
if [[ "$wget_install" == "y" || "$wget_install" == "yes" ]]

Last edited by suicidaleggroll; 08-06-2012 at 02:42 PM.
 
Old 08-06-2012, 02:50 PM   #12
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,568

Rep: Reputation: 411Reputation: 411Reputation: 411Reputation: 411Reputation: 411
Quote:
Originally Posted by suicidaleggroll View Post
FYI - a working if could have looked like:
Code:
if [[ "$wget_install" == "y" || "$wget_install" == "yes" ]]
I have read that the format here works but I have never been able to get it to work, as an altnerate I always use:

Code:
if [ "$wget_install" -eq "y" ] || [ "$wget_install" -eq "yes" ]
Not to hijack the thread but can anyone shed some light on why this occurs? I believe it is related to the "[[" double brackets and its probably me only using single brackets but want to confirm.
 
Old 08-06-2012, 03:02 PM   #13
suicidaleggroll
Senior Member
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 2,813

Rep: Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996Reputation: 996
Quote:
Originally Posted by Kustom42 View Post
I have read that the format here works but I have never been able to get it to work, as an altnerate I always use:

Code:
if [ "$wget_install" -eq "y" ] || [ "$wget_install" -eq "yes" ]
Not to hijack the thread but can anyone shed some light on why this occurs? I believe it is related to the "[[" double brackets and its probably me only using single brackets but want to confirm.

-eq is used for integer comparison, == is used for string comparison. This page gives a nice rundown of the differences between "[" and "[[".

http://mywiki.wooledge.org/BashFAQ/031

Essentially it boils down to "[" is older and more compatible, "[[" is newer and more powerful.

Last edited by suicidaleggroll; 08-06-2012 at 03:03 PM.
 
1 members found this post helpful.
Old 08-06-2012, 03:07 PM   #14
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,568

Rep: Reputation: 411Reputation: 411Reputation: 411Reputation: 411Reputation: 411
Thanks for the clarification suicidaleggroll.
 
Old 08-06-2012, 03:08 PM   #15
whizje
Member
 
Registered: Sep 2008
Location: The Netherlands
Distribution: Slackware64 current
Posts: 583

Rep: Reputation: 129Reputation: 129
nevermind
http://tldp.org/LDP/abs/html/testcon...ml#DBLBRACKETS
The [[ ]] construct is the more versatile Bash version of [ ]. This is the extended test command, adopted from ksh88.
Using the [[ ... ]] test construct, rather than [ ... ] can prevent many logic errors in scripts. For example, the &&, ||, <, and > operators work within a [[ ]] test, despite giving an error within a [ ] construct.
Arithmetic evaluation of octal / hexadecimal constants takes place automatically within a [[ ... ]] construct.

Last edited by whizje; 08-06-2012 at 03:09 PM. Reason: to late
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Linux bash script: sort command - not sorting properly lulwot Programming 3 04-19-2011 07:28 PM
[SOLVED] Help Running a Check in Bash Script Duo11 Linux - General 14 04-04-2011 08:15 AM
Performing fast search with a bash script jitendriya.dash Linux - General 7 06-04-2009 12:54 AM
Need help with building an RPM and performing a check in the build phase jakev383 Red Hat 1 12-10-2008 01:44 PM
how to have bash script check whether it's a x session? bkeeper Linux - Newbie 9 02-21-2006 06:31 AM


All times are GMT -5. The time now is 05:39 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration