You are not logged in.

#26 2009-04-24 19:24:37

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

hmm.. i got the menu up'n'going... echo'ed the entire menu part to a file and eval $(cat menufile) to load dialog... but i cant get the output working..

normally

2> outputfile

at the end of the menu would give me what i need, but in this case, it seems  i cant put 2> in either the "menufile" or after eval $()....

clueless.... please help hmm

Last edited by endre84 (2009-04-24 19:25:17)

Offline

#27 2009-04-24 20:01:00

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Simple bash scripting help needed..

what program is generating the actual dialog? is it zenity? and 2>$outputfile basically prints STDERR (the 'choice') back to $outputfile? if that's the case, the 2>$outputfile needs to be immediately after the command that is going to report back that STDERR.

maybe can i see the whole script?

Offline

#28 2009-04-24 20:43:32

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

this is my first script ever, so be nice, and test at your own risk wink

hope you can help! smile

#!/bin/bash

# SETTING MAIN VARIABLES
APPNAME="Arch Config Manager"
APPVER="0.1"
APPINFO="This is a utility for managing the \n primary configurations in Arch Linux."
TEMPFILE="/root/tempfile"

# DETECT WHETER TO RUN DIALOG OR XDIALOG
if [ -z $DISPLAY ]
then
    DIALOG="dialog"
else
    DIALOG="dialog"
#    DIALOG="Xdialog"
fi

# MENU - MAIN
function menu_main {
    $DIALOG --clear --cancel-label "Exit" --title "$APPNAME v$APPVER" --menu "$APPINFO" 20 65 8 \
    "/etc/rc.conf" "System Configuration" \
    "/etc/fstab" "Filesystem Mountpoints" \
    "/etc/mkinitcpio.conf" "InitRamFS Configuration" \
    "/etc/modprobe.conf" "Kernel Modules" \
    "/etc/resolv.conf" "DNS Servers" \
    "/etc/hosts" "Network Hosts" \
    "/etc/hosts.deny" "Denied Network Services" \
    "/etc/hosts.allow" "Allowed Network Services" \
    "/etc/locale.gen" "GlibC Locales" \
    "/etc/pacman.d/mirrorlist" "Pacman Mirrorlist" \
    "/etc/pacman.conf" "Pacman Configuration" \
    "/boot/grub/menu.lst" "Grub Boot Menu" \
    2> $TEMPFILE

    OUTPUT=`cat $TEMPFILE`
    rm -f $TEMPFILE
    if [ "$OUTPUT" = "/etc/rc.conf" ]; then
        menu_rcconf
    elif [ "$OUTPUT" = "/etc/pacman.conf" ]; then
        menu_pacmanconf
    fi
}

# MENU - RC.CONF
function menu_rcconf {
    FILE="/etc/rc.conf"

    $DIALOG --clear --title "/etc/rc.conf" \
    --menu "These are the available options in rc.conf, select one to edit." 25 50 17 \
    "LOCALE" "Sets the default language information." \
    "HARDWARECLOCK" "Sets the system clock to localtime or UTC." \
    "USEDIRECTISA" "Use direct I/O requests instead of /dev/rtc for hwclock." \
    "TIMEZONE" "Sets the timezone." \
    "KEYMAP" "Sets your keyboard layout language." \
    "CONSOLEFONT" "Sets which console font to use." \
    "CONSOLEMAP" "Sets which console map to use." \
    "USECOLOR" "Selects wheter or not to use ANSI color sequenses in startup messages." \
    "MOD_AUTOLOAD" "Allows autoloading of modules at boot and when needed." \
    "MODULES" "Modules to load at boot." \
    "USELVM" "Scan for LVM at startup, required if you use LVM." \
    "HOSTNAME" "Sets your computer hostname." \
    "INTERFACES" "Interfaces to start at boot." \
    "GATEWAY" "Set the default gateway." \
    "ROUTES" "Declare routes." \
    "NETWORKS" "Edit network profiles." \
    "DAEMONS" "Set which daemons to run at boot." \
    "Back" "Return to the previous menu"\
    2> $TEMPFILE

    OUTPUT=`cat $TEMPFILE`
    rm -f $TEMPFILE

    MENU_INPUT="LOCALE TIMEZONE KEYMAP CONSOLEFONT CONSOLEMAP HOSTNAME"
    MENU_LIST="MODULES INTERFACES ROUTES NETWORKS DAEMONS"
    MENU_YESNO="USEDIRECTISA USECOLOR USELVM"
    
    if echo "${MENU_INPUT}" | grep "$OUTPUT"; then
        menu_input
    elif echo "${MENU_LIST}" | grep "$OUTPUT"; then
        menu_list
    elif echo "${MENU_YESNO}" | grep "$OUTPUT"; then
        menu_yesno
    elif [ "$OUTPUT" = "Back" ]; then
        menu_main
    fi
}

# MENU INPUT
function menu_input {
    eval $(grep ^$OUTPUT $FILE)
    
    $DIALOG --clear --title "$OUTPUT Configuration" \
    --inputbox "Enter the new value for $OUTPUT here: [${!OUTPUT}]" 16 51 \
    2> $TEMPFILE

    NEWVALUE=`cat $TEMPFILE`
    rm -f $TEMPFILE
    
    [ -z "$NEWVALUE" ] && exit
    sed -i "/$OUTPUT/s/${!OUTPUT}/$NEWVALUE/" $FILE

    menu_main
}

function menu_yesno {
    eval $(grep ^$OUTPUT $FILE)
    
    $DIALOG --clear --title "$OUTPUT Config" \
    --yesno "Select new value for $OUTPUT: [${!OUTPUT}]" 6 61 \
    
    RETVAL=$?
    case $RETVAL in
        0)
            NEWVALUE="yes";;
        1)
            NEWVALUE="no";;
        255)
            menu_main;;
    esac
    
    [ -z "$NEWVALUE" ] && exit
    sed -i "/$OUTPUT/s/${!OUTPUT}/$NEWVALUE/" $FILE
    menu_main
}


# SO THIS IS WHERE THE PROBLEM IS
# BELOW IS THE MENU FOR CONFIGS
# THAT NEED A LIST TO BE EDITED
# I CANT GET THE OUTPUT WORKING

function menu_list {

# VIEWFILE IS USED FOR NOW
# UNTILL I GET I WORKING
# THEN I USE $TEMPFILE
rm viewfile

echo "$(grep ^$OUTPUT $FILE)" > $TEMPFILE
sed -i "/^$OUTPUT/s/(/\"/" $TEMPFILE # ALSO, HOW CAN I SHORTEN THESE "sed" TO ONE?
sed -i "/^$OUTPUT/s/)/\"/" $TEMPFILE
eval $(grep ^$OUTPUT $TEMPFILE)
echo ${!OUTPUT}
rm $TEMPFILE

echo "dialog --clear --title \"rcconf\" --checklist \"info\" 25 50 17 \\" >> viewfile
COUNT="1"
for NAME in ${!OUTPUT}; do
    if [ "$NAME" = "$(echo $NAME | tr -d '!')" ]; then
        echo "\"$COUNT\" \"$NAME\" \"on\" \\" >> viewfile
    else
        echo "\"$COUNT\" \"$(echo $NAME | tr -d '!')\" \"off\" \\" >> viewfile
    fi
    COUNT=$((COUNT+1))
done

# THIS EVAL LAUNCHES DIALOG
eval $(cat viewfile)
# BUT I CANT FIGURE OUT HOW TO GET THE OUTPUT NOW...

}


# SCRIPT STARTUP COMMANDS
menu_main
exit 0

Offline

#29 2009-04-24 21:31:53

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Simple bash scripting help needed..

you missing the beauty of bash expansion!

to see it in action do this:

1 - build $viewfile and stop (just add "exit" immediately after that line)

2 - `cat $viewfile` right from the commandline (can't use the variable name obviously) to see see what it looks like

now, think about this: you're building a file that you want to "drop in" to this script.  but by using "eval" on that file, the command you're running is actually "eval" not "dialog"; hence, you're redirecting STDERR (2>) from "eval" into $TEMPFILE (which is undesired). 

to get around this, don't build the command itself into the file then use "eval".  just build the _options_ into the file then "drop in" those options via the bash expansion of "$(cat $viewfile)" which takes what you just saw by cat'ting $viewfile manually and places it in the proper place after the command "dialog" and before the STDERR redirect 2>$TEMPFILE.  now the command you're actually running is "dialog", you get the options from $viewfile and the 2> that you're redirecting is actually what you're looking for.  at least that's my _theory_ wink

SPOILER: i've added the lines here; if you want to go off and try it yourself first stop reading here...



=====

viewfile="/path/to/some/tempfile.txt"

echo "--clear --title \"rcconf\" --checklist \"info\" 25 50 17 \\" >> $viewfile
COUNT="1"
for NAME in ${!OUTPUT}; do
    if [ "$NAME" = "$(echo $NAME | tr -d '!')" ]; then
        echo "\"$COUNT\" \"$NAME\" \"on\" \\" >> viewfile
    else
        echo "\"$COUNT\" \"$(echo $NAME | tr -d '!')\" \"off\" \\" >> viewfile
    fi
    COUNT=$((COUNT+1))
done

$DIALOG $(cat $viewfile) 2>$TEMPFILE

NOTE: UNTESTED

the beauty of bash scripting is you can try small portions of your code individually right from CLI (assuming you're in bash) to get an intuition about how things will work and react once scripted.

Offline

#30 2009-04-24 21:57:31

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

i actually tried that.. but the menu gets all screwed up if i do "dialog $(cat ...) .." therefore i ended up with eval. so this dont work.. sad

perhaps you can test the script? and hopefully find a sollution... i havent had any accidents yet.. worst case scenario you end up changing your hostname to xxx.. smile that is if your using arch.. thanks for the help anyway ..

im reading as cracy on various bash toturials, but i've learned the most from the codes posted here in the forum..

any suggestions for this?

sed -i "/^$OUTPUT/s/(/\"/" $TEMPFILE # ALSO, HOW CAN I SHORTEN THESE "sed" TO ONE?
sed -i "/^$OUTPUT/s/)/\"/" $TEMPFILE

Offline

#31 2009-04-24 22:15:59

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

seems like "2> $file" does'nt like to be below the last list item.. so

...
"5" "whatever" "on" \
2> $file

does'nt work, but..

"5" "whatever" "on" 2> $file

gives me output, but not in the ordinary manner i think.. but i can work with that..
..it gives me:

"1" "3" "5"

when i have turned 2 and 4 "off"


so i need to change the "for" loop you wrote, so that i can add "2> $file" right after the last item, and without the last "\"... i'll try to figure out the "for" loop..

Last edited by endre84 (2009-04-24 22:21:31)

Offline

#32 2009-04-25 00:37:16

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Simple bash scripting help needed..

just put the echo right after the for loop (not inside or it'll repeat each loop), should be good to go.


also note, >> appends to a file so if you run your script multiple times without cleaning $viewfile in between it could end up with repeated entries throwing off your menu.

Offline

#33 2009-04-25 01:01:13

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Simple bash scripting help needed..

hiyoo!

#!/bin/bash

# SO THIS IS WHERE THE PROBLEM IS
# BELOW IS THE MENU FOR CONFIGS
# THAT NEED A LIST TO BE EDITED
# I CANT GET THE OUTPUT WORKING

DIALOG="dialog"
TEMPFILE="/tmp/outfile"
viewfile="/tmp/viewfile"

# hehe
names='homer !marge lisa !maggie bart'

# clean the viewfile if it exists
[ -f $viewfile ] && rm $viewfile
touch $viewfile

# print first line into viewfile
echo "--clear --title rcconf --checklist info 25 50 17" >> $viewfile

COUNT=1

# check the names for !
for NAME in $names; do
    if [ "$NAME" = "$(echo $NAME | tr -d '!')" ]; then
        echo "$COUNT $NAME on" >> $viewfile
    else
        echo "$COUNT $(echo $NAME | tr -d '!') off" >> $viewfile
    fi
    COUNT=$((COUNT+1))
done

dialog $(cat $viewfile) 2>$TEMPFILE

cat $TEMPFILE

exit 0

Offline

#34 2009-04-25 18:01:56

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

i tried some aproaches now..

1: echo'ing without dialog in the first line, executing the external menu file with dialog instead of eval, and putting 2> after $(cat...).. ERROR
                dialog $(cat $viewfile) 2>$TEMPFILE
2: echo'ing " 2> outfile " to the last line and executing with eval.. ERROR
3: puttingh 2> after the eval line... ERROR

the only way i can do this is to add 2> outfile to the last menu item line..

"5" "bart" "on" 2> outfile            = WORKING

the below doesnt work for some reason, althoug if i put the menu list inside the script it works..

"5" "bart" "on" \
2> outfile                   = NOT WORKING


i need to either change the for loop or change the last line after the for loop is done..
so i was thinking to use sed to alter the last line and add 2> outfile

so what sed line do i need to do this change?

from:
"5" "bart" "on" \
"*" "*" "*" \

to:
"5" "bart" "on" 2> outfile
"*" "*" "*" 2> outfile

where "5", "bart" and "on" will need to be "wildcards" (*)

so again with my messy explenations... :-P

Last edited by endre84 (2009-04-25 18:02:33)

Offline

#35 2009-04-25 18:18:01

klixon
Member
From: Nederland
Registered: 2007-01-17
Posts: 525

Re: Simple bash scripting help needed..

sed 's/\\/2> outfile/'

If i understand you right, that is lol


Stand back, intruder, or i'll blast you out of space! I am Klixon and I don't want any dealings with you human lifeforms. I'm a cyborg!

Offline

#36 2009-04-25 18:27:36

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

klixon wrote:
sed 's/\\/2> outfile/'

If i understand you right, that is lol

not quite... but i figured it out.. i needed only the last line in the script to be modified and to leave the rest intact..

instead of changing only the last line, i merged every line into one and removed the backslashes with sed.. so...

sed -e :a -e '/\\$/N; s/\\\n//; ta'

will remove the backslashes and merge all lines into one.. then i execute the dialog with eval... this works, but maybe theres a better way of doing this..?

function menu_list {

# $OUTPUT="NAMES=(marge !homer bart lisa !maggie)"
echo "$(grep ^$OUTPUT $FILE)" > $TEMPFILE

# replace ( & ) with "
sed -i "/^$OUTPUT/s/(/\"/g;/^$OUTPUT/s/)/\"/g" $TEMPFILE

# define the var $NAMES
eval $(grep ^$OUTPUT $TEMPFILE)

# cleanup
rm $TEMPFILE

echo "dialog --clear --title \"rcconf\" --checklist \"info\" 25 50 17 \\" >> menufile
COUNT="1"
for NAME in ${!OUTPUT}; do
    if [ "$NAME" = "$(echo $NAME | tr -d '!')" ]; then
        echo "\"$COUNT\" \"$NAME\" \"on\" \\" >> menufile
    else
        echo "\"$COUNT\" \"$(echo $NAME | tr -d '!')\" \"off\" \\" >> menufile
    fi
    COUNT=$((COUNT+1))
done
echo "2> outputfile" >> menufile

eval $(sed -e :a -e '/\\$/N; s/\\\n//; ta' menufile)

}

any suggestions?

Last edited by endre84 (2009-04-25 18:52:50)

Offline

#37 2009-04-25 23:18:06

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Simple bash scripting help needed..

did you try my code in post 33? it seemed to work correctly over here; just needs to be tweaked/merged back into your original.

Offline

#38 2009-04-26 08:28:41

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

brisbin33 wrote:

did you try my code in post 33? it seemed to work correctly over here; just needs to be tweaked/merged back into your original.

yes i tried it.. i get some error.. "expected 4 have only 3" or something... think its a dialog error..
the same thing happens if i put " dialog --clear --title "rcconf" " and " --checklist "info" 25 50 17 " in two lines instead of one..
but it works now, atleast, with the new eval $(sed......)

Offline

#39 2009-04-26 16:14:43

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Simple bash scripting help needed..

endre84 wrote:
brisbin33 wrote:

did you try my code in post 33? it seemed to work correctly over here; just needs to be tweaked/merged back into your original.

yes i tried it.. i get some error.. "expected 4 have only 3" or something... think its a dialog error..
the same thing happens if i put " dialog --clear --title "rcconf" " and " --checklist "info" 25 50 17 " in two lines instead of one..
but it works now, atleast, with the new eval $(sed......)

that's really wierd; just so you know i'm not a liar...

see the code, run the code:

> cat .bin/testing 
#!/bin/bash

# define some things
DIALOG="dialog"
TEMPFILE="/tmp/outfile"
viewfile="/tmp/viewfile"

# $names can come from anywhere...
names='homer !marge lisa !maggie bart'

# clean the viewfile if it exists
[ -f $viewfile ] && rm $viewfile
touch $viewfile

# print first line into viewfile
echo "--clear --title rcconf --checklist info 25 50 17" >> $viewfile

COUNT=1

# check the names for !
for NAME in $names; do
    if [ "$NAME" = "$(echo $NAME | tr -d '!')" ]; then
        echo "$COUNT $NAME on" >> $viewfile
    else
        echo "$COUNT $(echo $NAME | tr -d '!') off" >> $viewfile
    fi
    COUNT=$((COUNT+1))
done

dialog $(cat $viewfile) 2>$TEMPFILE

exit 0

> .bin/testing

checklist looks good...
dialog_pre.png
make my selections...
dialog_post.png
view the output file...

> cat /tmp/outfile 
"1" "2" "3"

oh well, glad you got it working smile

Offline

#40 2009-04-28 08:17:27

raf_kig
Member
Registered: 2008-11-28
Posts: 143

Re: Simple bash scripting help needed..

Some random style suggestions :-)

For readability: Instead of

if [ "$NAME" = "$(echo $NAME | tr -d '!')" ]; then
    foo
else
    bar
fi

use

case $NAME in
    \!*)  
        foo ;;
    *)
        bar ;;
esac

And instead of evaluating your variable just to save it again just increment it, ie instead of

COUNT=$((COUNT+1))

use

((COUNT++))

or

((COUNT += 1))

regards

raf

Offline

#41 2009-05-04 19:47:29

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

Procyon wrote:

You need variable indirection: ${!var}

So:
$ conf=TIMEZONE
$ file=/etc/rc.conf
$ eval $(grep ^$conf $file)
$ echo ${!conf}
Europe/Oslo

I added a ^ because there is also a timezone string in the comments

So i've been using this "variable indirection" in various places in my script, and now i need to add a word into this variable, how can i do this?

examle:

echo "${!conf}"
> homer marge bart lisa

new="maggie"
${!conf}="${!conf} $new"

echo "${!conf}"
> homer marge bart lisa maggie

i have to do some major rewrites if there's no sollution to this, so hopefully someone knows how!?! hmm

Offline

#42 2009-05-04 20:07:20

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Simple bash scripting help needed..

Have a look here: http://wooledge.org:8000/BashFAQ/006

$ simpsons="bart lisa"
$ conf=simpsons
$ echo "${!conf}"
bart lisa
$ new="homer marge"
$ read $conf <<< "${!conf} $new"
$ new="maggie"
$ printf -v $conf "${!conf} $new"
$ echo "${!conf}"
bart lisa homer marge maggie

Offline

#43 2009-05-04 21:05:32

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

awesome! thanks.. i'll make shure to read up on variable redirection smile

Offline

Board footer

Powered by FluxBB