LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   BASH variables evaluation question. (http://www.linuxquestions.org/questions/programming-9/bash-variables-evaluation-question-80471/)

Thetargos 08-09-2003 03:28 PM

BASH variables evaluation question.
 
Hi all, I have a problem... I am trying to write a script and need a way to sort out the "value" asigned to a variable so it can be then evaluated. I am not very good at describing, so I'll write what I have so far and ask you about what I actually want later:

Code:

#!/bin/bash
echo "Kernel vesion?"
read KERNVER

---conflicting portion follows----

#Find out if the sources are in place

LIST=`ls /usr/src | grep $KERNVER`

----Rest of the code goes here---

If leave the LIST variable have the value from the grep command, it will have as its value the whole output form grep, right? so I end up with something like this in my system (assuming I exported the above result of the ls|grep):
Code:

$ echo $LIST
LIST=linux-2.4 linux-2.4.20-18.9 linux-2.4.21 linux-2.4.21-ck1
linux-2.4.21-ck1.patch linux-2.4.21-SuMo linux-2.4.21.tar.bz2
supermount-1.2.8-2.4.21.patch
$

Now, my question is: How do I retrieve the space separated values from LIST? is it as valid as $1, $2, etc?

Help, I'm desperate!

PS: It occured to me that I would do it if I asigned the value to LIST if I previously had written a file with the grep command output and then evaluated that file with lets say awk or gawk... What do you think?

kev82 08-09-2003 04:00 PM

you could use a bash for loop to pick out each individually.

for i in $LIST; do echo $i; done

to use awk theres no need to write the output to a file just

echo $LIST | awk [options]

jhorvath 08-09-2003 04:38 PM

here's my crappy example :

Code:

#!/bin/bash

SRCROOT="/usr/src"
KERNVER=`uname -r`
echo "Your current kernel version is : ${KERNVER}"

LIST=`ls ${SRCROOT} | grep ${KERNVER}`
echo "These files are in ${SRCROOT} : "

for EACHFILE in ${LIST}; do echo ${EACHFILE}; done

[EDIT]
the values stored in ${LIST} are actualy newline "\n" seperated, i know it looks like a space but it's not
[/EDIT]

[EDIT]
modified substantially , i did it the long way, mr. kev82's way is much cleaner ;)
(i was posting while he was...and he won ;)
[/EDIT]

Thetargos 08-10-2003 12:15 AM

Thank you guys!! I was also thinking about using the -o option to the grep command so that it would just fit the exact pattern I was looking for (though the "for" options looks GREAT!) like this:
Code:

#!/bin/bash
#script to test if a kernel source tree exists
KERNVER="linux-$1"
if [ "$KERNVER" = "" ]
  while :
  do
      echo "You did not supply a kernel version as an argument"
      echo "What kernel version would you like to check for?"
      read KERNVER
  done
fi

LIST=`ls /usr/src | grep -o $KERNVER`
if [ "$LIST" = "" ]
  then
        echo "That version of kernel has no sources installed"
        exit 1
    elif [ "$LIST" != "" ]
        then
              echo "The sources wer found at /usr/src/$LIST"
fi

I must admit that the "for" loop solution looks more promising, thank you guys again.

[/edit]
PS: Pardon my bad programing style... just a newb here :D

Thetargos 08-10-2003 01:02 AM

Another rather dumb question (I haven't seen any case of it, but also haven't seen that it is not permited) is it possible to have nested "case" switches (as in C switches)?

[/edit]
When I finish the script I am working on (and proved that it works correctly :) ) I'll post it here :D

Thanks for your patience.

Thetargos 08-10-2003 05:02 AM

Ok my report so far... I found out that indeed I can have nested cases, and the "for" loop solution is elegant, not to say excelent. I don't wanna post all of the progress I am making on this script... but I'll post what the final solution was to the LIST problem... I think it is elegant and efficient (again my programming style may offend some, I know I'm like a brute at this :D) Well here it is:

Code:

#!/bin/bash
#Test script for looking up Kernel sources.

KERNVER="linux-$1"
KERNSRC="/usr/src"

if [ "$KERNVER" = "" ]
then
        while :
        do
                echo "You did not supply any kernel version as an argument"
                echo "Enter a kernel version you'd like to look up"
                read KERNEL
                KERNVER="linux-$KERNEL"
        done
fi

# Find out whether or not the sources for the linux kernel version supplied exist
# on /usr/src, otherwise prompt for the location of the source tree.

LIST=`ls /usr/src | grep $KERNVER`
for i in $LIST
do
        if [ "$i" = "$KERNVER" ]
        then
                echo
                echo "The kernel version you entered is on ${KERNSRC}/${KERNVER}"
                break
        elif [ "$i" != "$KERNVER" ]
        then
                echo "The kernel version you supplied does not exist at $KERNSRC"
                echo "Please enter the path to the source tree"
                read KERNSRC
        fi
done

KERNSRC="${KERNSRC}/${KERNVER}"

# Test if the given path is a directory and if it is writable and accesible       
# by the current user.

if [ ! -d "$KERNSRC" ]
then
        echo "The kernel version you entered is not a directory!"
        exit 1
elif [ ! -x "$KERNSRC" ]
then
        echo "The kernel source tree is not accesible by user $USER."
        echo "Please change the permissions on the directory or run as root"
        exit 2
elif [ ! -w "$KERNSRC" ]
then
        echo "The kernel source tree is not writeable by user $USER."
        echo "Please change the permissions on the directory or run as root"
        exit 3
fi

What do you think of this solution?? I still need to test it intensively so to make sure it is as bugfree code as possible, but I think I'm improving...

Again, thanks guys your help was (both examples, actually) INVALUABLE. :D

Here I go again with a (I think) rather dumb question... Is it possible to have script run a program, for instance a network configuratoin tool, and as soon as you exit the application opened by the script, the control was returned to the script subshell? If so... (I can imagine it would be QUITE hard to accomplish) where can I find information about that?

/bin/bash 08-10-2003 12:24 PM

Yes you can have nested case.
Code:

#!/bin/bash
#Endless loop
while :
do
      echo; echo "Hit a key, then hit return."
      read Keypress

      case "$Keypress" in
        [a-z]  ) echo "Lowercase letter";;
        [A-Z]  ) echo "Uppercase letter";;
        [0-9]  ) echo "Digit";;
        *      ) echo "Punctuation, whitespace, or other"
      #Here is an embedded case
        case "$Keypress" in
        !        ) echo "Exclamation mark!";;
        ,        ) echo "Comma";;
        .        ) echo "See ya, wouldn't wanna be ya."
                exit 0;;
        *        ) echo "You got me.  I cant figure it out?";;
        esac;;
      esac
done 

exit 0

To have a script execute a program just put it in the script like you would type it on the command line.

itzamna 08-10-2003 02:36 PM

as a newbie and new at this site, i'm not sure if this question goes here, you may guide me to look into a better forum for my question:
i'm trying to learn more options for the command 'cp'; if i have 100 files called from FILE_001.ABC to FILE_100.ABC and i want to copy'em to anotherfile_001.abc - anotherfile_100.abc, how could i do it withoug repeating 100 times 'cp'?
i thought it could be something like
% cp FILE_[001-100].ABC anotherfile_[001-100].abc
but looks like i really need to know more about what i'm doing here;
also, does somebod know a site with good examples of all this sort of bash tricks? i find 'man' and 'info' quit hard to follow;
thank you!

slapNUT 08-10-2003 04:06 PM

Something like this.

cp FILE_[0-1][0-9][0-9].ABC
However this will copy from 000-199
cp FILE_0[0-9][0-9].ABC
This copies 000-099 then you just need to add 100

The thing is when you copy multiple files you have to specify a directory as the destination. To rename the files you need to loop through a list.

something like:
FILE=`ls FILE_0[0-9][0-9].ABC`
for i in $FILE; do
cp $i `echo $i|sed -e's/FILE/anotherfile/' -e's/ABC/abc/'`
done

slapNUT 08-10-2003 04:12 PM

Go to www.tldp.org and you will find the Advanced Bash-Scripting Guide.

Thetargos 08-10-2003 04:42 PM

/bin/bash:

What I meant by asking about the calling up applications on scripts, was because I would like a script I'm working on to call up an application (Mozilla if you really wanna know) and then if ever the application is terminated, instead of returning control to the shell on which the script was executed in the first place, it would return control to the scritp so it can take action up on exit of that program (whether it be to restart Mozilla or to close the session, etc, depending on the exit status of the called program). I know this would not be easy to program, but I would like to know where could I get information about this kind of BASH script programming (ok scripting... I know scripting is not programming :D).

/bin/bash 08-11-2003 04:11 AM

OK, then just type it in like a normal command and it will cause the shell to wait. If you add & then the process will operate in the background e.g.

#!/bin/bash
scripting stuff here
/usr/local/bin/ymessenger &
/usr/bin/mozilla
cleanup stuff here
exit 0

ymessenger will execute in the background and the script will continue. Mozilla will execute and the script will wait for it to terminate before the cleanup starts.



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