LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 01-26-2013, 02:33 PM   #16
druadunc91
LQ Newbie
 
Registered: Jan 2013
Posts: 28

Original Poster
Rep: Reputation: Disabled

Quote:
clear
echo;echo;echo
echo -n Enter something:' '
read x


if [ "$x" == "time" ]
then
`date`
elif [ "$x" == "Directory" ]
then
`pwd`
elif [ "$x" == "Who" ]
then
`who`
elif [ "$x" -le "9" ]
then
echo You entered a single digit number
else
echo You entered a number
elif [ "$x" == "Quit" ]
then
echo Something

fi
the bolded part is the part with the error
 
Old 01-26-2013, 02:40 PM   #17
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Quote:
Originally Posted by druadunc91 View Post
Code:
if [ "$x" == "time" ]
then
 `date`
elif [ "$x" == "Directory" ]
then
 `pwd`
elif [ "$x" == "Who" ]
then
 `who`
elif [ "$x" -le "9" ]
then
 echo You entered a single digit number
else  # else needs to be last in the chain (if then elif then elif then else fi)
 echo You entered a number
elif [ "$x" == "Quit" ]   # see previous comment.
 then
 echo Something
fi
Have a look here: (BGFB) 7.2.1. if/then/else constructs

Last edited by druuna; 01-26-2013 at 02:45 PM. Reason: command -> comment
 
1 members found this post helpful.
Old 01-27-2013, 03:23 PM   #18
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Please use ***[code][/code]*** tags around your code and data, to preserve the original formatting and to improve readability. Do not use quote tags, bolding, colors, "start/end" lines, or other creative techniques.

1) When using bash or ksh, it's recommended to use [[..]] for string/file tests, and ((..)) for numerical tests. Avoid using the old [..] test unless you specifically need POSIX-style portability.

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

2) When doing simple pattern matching on a variable string, a case statement is generally better to use. Unfortunately you can't do arithmetic comparisons in them (not directly, at least), but you can usually include a separate if statement either as a sub-command or as a separate one before or after it.

3) Finally, the shell has built-in variables for $PWD, $HOME, $USER and several others, so there's often no need for the external commands. See the bash man page.

Code:
clear
echo;echo;echo
echo -n Enter something:' '
read x

case ${x,,} in		#the "${var,,}" pattern forces the expansion to lowercase
                        #simplifying the pattern matching
    quit)
        echo "goodbye"
        quit
    ;;
    time)
        date
    ;;
    directory)
        echo "$PWD"
    ;;
    who)
        echo "$USER"
    ;;
    *[^0-9]*)		#the string contain non-digit characters
        echo "you entered an unknown text string"
    ;;
    [0-9]*)
        if (( $x <= 9 )); then
            echo "You entered a single digit number"
        else 
            echo "You entered a multi-digit number"
        fi
    ;;

esac
 
2 members found this post helpful.
Old 01-27-2013, 04:13 PM   #19
druadunc91
LQ Newbie
 
Registered: Jan 2013
Posts: 28

Original Poster
Rep: Reputation: Disabled
David,

thanks for the help. The reason I am using [] is because that is how my professor is teaching us right now. The help though is much appreciated and if I have more questions, I will keep posting.

Thanks for all the help so far everyone!
 
Old 01-28-2013, 07:22 PM   #20
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Do read the links given to you and please indent your code as shown above, its much easier to read that way.
Also, you can debug your code by using
Code:
set -xv
at the top
 
Old 01-28-2013, 09:07 PM   #21
druadunc91
LQ Newbie
 
Registered: Jan 2013
Posts: 28

Original Poster
Rep: Reputation: Disabled
Code:
clear
echo;echo;echo
echo -n Enter something:' '
read x

        if [ "$x" == "Directory" ]
        then
        pwd
                elif [ "$x" == "Date" ]
                then
                date
                        elif [ "$x" == "Who" ]
                        then
                        who
                                elif [ ${#x} -gt 20 ]
                                then
                                echo "Stop over achieving, stick with less than 20 characters"
                                        elif [ "$x" == "Time" ]
                                        then
                                        date +%H:%M
                                                elif [ "$x" == "Quit" ]
                                                then
its not the finished code...i could have sworn I saved it last time i edited it. well, i'll fix it later...anyways, everything here works

Last edited by druadunc91; 01-28-2013 at 09:08 PM.
 
Old 01-29-2013, 01:38 AM   #22
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
As above, prefer [[ ]] to [ ] http://tldp.org/LDP/abs/html/testcon...ml#DBLBRACKETS
 
Old 01-31-2013, 12:55 PM   #23
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Re post #21, That's not the way to properly indent your code. The idea is that all commands that occur at the same level of execution line up at the same level of indentation.

if, elif, else, and fi are all part of the same complex command enclosure, and so should line up, with the sub-commands that it executes under those conditions indented an extra level.

In addition, many people prefer to put the then keyword on the same line as the if, since it's not an independent command, but paired with the previous keyword to bracket the test commands. It's how the shell knows where the test ends and the subcommands start. Putting them on the same line helps keep this visually clear and separate from the sub-commands (this can be relaxed if the test commands themselves occupy multiple lines).

This suggestion also applies to the do keyword in for/while loops.

Pay attention to vertical spacing too, which helps to visually define blocks that go together.

And finally, get into the habit now of commenting your code clearly as you're writing. You'll be very thankful for them when you start reviewing old scripts you wrote and start wondering what the heck you were thinking when you wrote it!

See here for more on good styling practice: Scripting With Style

Code:
clear

echo;echo;echo
echo -n Enter something:' '

read x

if [ "$x" == "Directory" ]; then
    pwd
elif [ "$x" == "Date" ]; then
    date
elif [ "$x" == "Who" ]; then
    who
elif [ ${#x} -gt 20 ]; then
    echo "Stop over achieving, stick with less than 20 characters"
elif [ "$x" == "Time" ]; then
    date +%H:%M
else
    if [ .... ]; then
        acommand
    else
        bcommand
    fi
fi
I fleshed it out at the end with an example of a sub-test to further illustrate proper nesting.

As I said before, a case statement would still be much better here, however, and the double-bracket tests.

Last edited by David the H.; 01-31-2013 at 01:01 PM. Reason: minor rewording
 
Old 01-31-2013, 01:28 PM   #24
druadunc91
LQ Newbie
 
Registered: Jan 2013
Posts: 28

Original Poster
Rep: Reputation: Disabled
Code:
clear
echo;echo;echo
echo -n Enter something:' '
read x

if [ "$x" == "Directory" ]
then
pwd

elif [ "$x" == "Date" ]
then
date

elif [ "$x" == "Who" ]
then
who

elif [ ${#x} -gt 20 ]
then
echo "Stop over achieving, stick with less than 20 characters"

elif [ "$x" == "Time" ]
then
hour="$(date +%H)"
        if [ "$hour" -ge "7" ] && [ "$hour" -le "12" ]
        then
        echo Morning
        elif [ "$hour" -ge "12" ] && [ "$hour" -le "17" ]
        then
        echo Afternoon
        elif [ "$hour" -ge "17" ] && [ "$hour" -le "20" ]
        then
        echo Evening
        elif [ "$hour" -ge "21" ] || [ "$hour" -le "4" ] && [ "$hour" -ge "0" ]
        then
        echo Night
        elif [ "$hour" -ge "4" ] && [ "$hour" -le "7" ]
        then
        echo

        fi

elif [ "$x" == "Quit" ]
then
echo "Bitch"

elif [ "$x" == "Quit" ]
then
echo "Bitch"

elif [[ $x =~ ^-?[0-9]+$ ]]
then
        if [ $x -ge 0 ] && [ $x -le 9 ] && [ ${#x} -eq "1" ]
        then
        echo "You entered a single digit  number"
        else
        echo "You have entered a number"
        fi
else
echo "$x"

fi
Here is the finished product. Everything worked the way it should and now, for my next assignment, I do exactly what I did here, but with case statements and not if statements
 
Old 01-31-2013, 05:32 PM   #25
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
As per David the H.'s example, you should indent all cmds between then .. elif, not just other 'if' blocks.
Same for else .. fi.
 
Old 02-04-2013, 04:53 PM   #26
druadunc91
LQ Newbie
 
Registered: Jan 2013
Posts: 28

Original Poster
Rep: Reputation: Disabled
im back again. Some more help would be appreciated

For this next assignment, I'm taking my finished code and instead of using if's and elif's, I'm using case statements to make the program do exactly as my last one.

this is what I have

Code:
clear
echo;echo;echo
echo -n Enter something here: " "
read x

case "$x" in
        Directory)
                pwd
                ;;

        Date)
                date
                ;;
        Who)
                who
                ;;

esac
right now, i'm trying to get the program to tell the user if they entered more than 20 characters that it is too many.

this is what I tried

Code:
clear
echo;echo;echo
echo -n Enter something here: " "
read x

case "$x" in
        Directory)
                pwd
                ;;

        Date)
                date
                ;;
        Who)
                who
                ;;
        ${#x} -gt 20)
                echo "Over achiever!!!"
                ;;

esac
as with what i did before where I had [ ] around that last statement with the if's and elif's, do I need the brackets around the that line or what is wrong with it to say they entered more than 20 characters?

Last edited by druadunc91; 02-04-2013 at 04:54 PM.
 
Old 02-05-2013, 01:32 AM   #27
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
@druadunc91: To my knowledge the case statements expects a pattern to compare to and not a true/false expression.

Here is one way to edit your code to do what you require:
Code:
# replace the following

        ${#x} -gt 20)
                echo "Over achiever!!!"
                ;;

# with

        * )
                if [ ${#x} -gt 20 ]
                then
                  echo "Over achiever!!!"
                fi
                ;;
There are probably other ways, this came to mind first.

Also have a look here: ABSG - 11.4. Testing and Branching
 
Old 02-05-2013, 01:39 AM   #28
druadunc91
LQ Newbie
 
Registered: Jan 2013
Posts: 28

Original Poster
Rep: Reputation: Disabled
Is there a way to do that expression without the if statement? This assignment is using just case statements
 
Old 02-05-2013, 01:59 AM   #29
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Quote:
Originally Posted by druadunc91 View Post
Is there a way to do that expression without the if statement? This assignment is using just case statements
Have a look at this:
Code:
        * )
                [ ${#x} -gt 20 ] && echo "Over achiever!!!"
                ;;
 
Old 02-09-2013, 08:21 AM   #30
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
As mentioned before, a case statement takes the input string and compares it to a list of globbing patterns. The first pattern that matches in the list has its commands executed. Each potential match is equivalent to a "[[ $var == *pattern* ]]" test.

The only way you could directly use a pattern match to calculate "more than/less than" would be something like this:
Code:
case $text in

    ?|??|???|????) echo "Contains less than 5 characters" ;;
    ?????????????????????*) echo "Contains more than 20 characters" ;;
    *) echo "Contains 5-20 characters" ;;

esac
You have to match an exact number of characters and use logical thinking to output the answers you want.

An easier technique may be to match the length of the string directly, within a range of numbers:

Code:
case ${#text} in

     [0-9]) echo "0-9 characters" ;;
    1[0-9]) echo "10-19 characters" ;;
    2[0-9]) echo "20-29 characters" ;;
         *) echo "30 or more characters" ;;
 
esac
Note finally that bash has extended globbing, which can give you even more matching flexibility.


In any case, druuna's example is certainly the way to go here. greater than/less than style matches really need bracket tests. But here again I would use an arithmetic evaluation instead.

Code:
(( ${#var} > 20 )) && echo "Contains more than 20 characters" ))

PS: your code is looking better. Keep up the good work!

Last edited by David the H.; 02-09-2013 at 08:31 AM. Reason: minor rewording & code changes
 
  


Reply



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
LXer: Share And Discover Cool Bash Tricks With Bash One-Liners LXer Syndicated Linux News 0 01-30-2012 09:50 AM
Bash problem : -bash: [: /bin/bash: unary operator expected J.A.X Linux - Software 1 09-22-2011 05:52 AM
[SOLVED] Using a long Bash command including single quotes and pipes in a Bash script antcore Linux - General 9 07-22-2009 11:10 AM
BASH -copy stdin to stdout (replace cat) (bash browser) gnashley Programming 4 07-21-2008 01:14 PM
why did bash 2.05b install delete /bin/bash & "/bin/sh -> bash"? johnpipe Linux - Software 2 06-06-2004 06:42 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 10:11 AM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration