You are not logged in.
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
Last edited by endre84 (2009-04-24 19:25:17)
Offline
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?
//github/
Offline
this is my first script ever, so be nice, and test at your own risk
hope you can help!
#!/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
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_
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.
//github/
Offline
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..
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.. 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
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
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.
//github/
Offline
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
//github/
Offline
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
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
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
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
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...
make my selections...
view the output file...
> cat /tmp/outfile
"1" "2" "3"
oh well, glad you got it working
//github/
Offline
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
You need variable indirection: ${!var}
So:
$ conf=TIMEZONE
$ file=/etc/rc.conf
$ eval $(grep ^$conf $file)
$ echo ${!conf}
Europe/OsloI 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!?!
Offline
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
awesome! thanks.. i'll make shure to read up on variable redirection
Offline