LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   set variables in a bash script; ansi PS1 color script (https://www.linuxquestions.org/questions/programming-9/set-variables-in-a-bash-script%3B-ansi-ps1-color-script-600808/)

donnied 11-19-2007 06:35 AM

set variables in a bash script; ansi PS1 color script
 
I've been working on a script to choose fg and bg colors for the terminal.
I'm unsure about setting the variables in bash and if I'm even leaving the first while loop. (The program just stops.) Csh has a set x = 12
but bash in bash which would be preferable x=30 , x=30m, or x="30m" ?
Code:

#!/bin/bash

fore=""
back=""
front=""
rear=""

clear
echo "Hello, you are logged in as " $USER". What foreground color would you like? "

sleep 1


echo "..........................."
echo "...........MENU............"
echo
echo "1 black "
echo "2 red "
echo "3 green "
echo "4 yellow"
echo "5 blue"
echo "6 purple"
echo "7 cyan"
echo "8 white"



read fore
while [ "$fore" != 0 ];
do
        case $fore in
                1)  front="[30m" ;;
                2)  front="[31m" ;;
                3)  front="[32m" ;;
                4)  front="[33m" ;;
                5)  front="[34m" ;;
                6)  front="[35m" ;;
                7)  front="[36m" ;;
 esac
done

echo "What background color would you like? "

sleep 1

#The Menu
echo "..........................."
echo "...........MENU............"
echo
echo "1 black "
echo "2 red "
echo "3 green "
echo "4 yellow"
echo "5 blue"
echo "6 purple"
echo "7 cyan"
echo "8 white"

read back
while [ "$back" != 0 ];
do
        case $back in
                1)  clear;
                  export rear=[40m ;
                  ;;
                2)  clear;
                  export rear=[41m ;
                  ;;
                3)  clear;
                  export rear=[42m ;
                  ;;
                4)  clear;
                  export rear=[43m ;
                  ;;
                5)  clear;
                  export rear=[44m ;
                  ;;
                6)  clear;
                  export rear=[45m ;
                  ;;
                7)  clear;
                  export rear=[46m ;
                  ;;
                8)  clear;
                  export rear=[47m ;
                  ;;
 esac
done
while [ "$back" = "$fore" ];
        do
        echo "You can't read that!!!!"
        ;;

while [ "$back"  != "$fore" ];
        do
        PS1="\[\033[0;$front;$rear\u@\h:\w\$ \]";
        ;;
done
exit


pixellany 11-19-2007 07:56 AM

You are testing for the value of a number, so you need to enter numbers only.

Note that x=30m and x="30m" give the same result---ie a string containing the characters 3, 0, and m. You would only need the quotes if the string has spaces.

colucix 11-19-2007 08:00 AM

I think it doesn't stop. Instead, it hangs inside the while loops:
Code:

while [ "$fore" != 0 ]
do
  <commands>
done

this literally means while the value of fore is different from 0 do <commands>, but since there is no statement which will assign zero to the variable, it results in an infinite loop. Furthermore, at the end of the script there are some syntax errors: it is not necessary to use a while loop to test a condition, simply use an if/then construct. Also the double semicolon is out of place (it is for terminating case conditions only). Regarding your original question you can always use double quotes to enclose a string value, but in most cases it is not strictly necessary.
Just a hint: to debug scripts when you are in doubt about syntax and/or shell expansion, you can try to launch the script by
Code:

bash -x <scriptname>
this will give a trace of all the executed command. In this case you would have immediately noticed the infinite loop issue.

Hobbletoe 11-19-2007 09:14 AM

I would also suggest the use of a select statement to create your menu. It would be something like ...

Code:

PS3="Enter foreground color choice:  "
select fgcc in black red green yellow blue purple cyan white exit
do
 case ${fgcc} in
  "black") export fgc=30;;
  "red") export fgc=31;;
  "green") export fgc=32;;
  "yellow") export fgc=32;;
  "blue") export fgc=34;;
  "purple") export fgc=35;;
  "cyan") export fgc=36;;
  "white") export fgc=37;;
  "exit") exit;;
  *) echo "Invalid Choice"
    exit;;
 esac
 break
done

It should save you some space. Check out Section 10.4 of the Advanced Bash-Scripting Guide for the select statement, Section 33.6 if you have any questions about using colors in bash.

Also, you will only want the "m" character at the end of your background color. Setting a color is
Code:

\e[<attribute>;<fg color>;<bg color>m
The m closes that meta character string. It is discussed in Section 33.6 linked above.

donnied 11-21-2007 11:33 AM

Well the using case made the code look fabulous and run smoothly. I completely abandoned the failed attempts using while and / or if statements. I am curious to know what went wrong.

The new script (basically written by Hobbletoe):
Code:


PS3="Enter foreground color choice:  "
select fgcc in black red green yellow blue purple cyan white exit
do
 case ${fgcc} in
  "black") export fgc=30;;
  "red") export fgc=31;;
  "green") export fgc=32;;
  "yellow") export fgc=32;;
  "blue") export fgc=34;;
  "purple") export fgc=35;;
  "cyan") export fgc=36;;
  "white") export fgc=37;;
  "exit") exit;;
  *) echo "Invalid Choice"
    exit;;
 esac
 break
done

PS3="Enter background color choice:  "
select bgcc in black red green yellow blue purple cyan white exit
do
 case ${bgcc} in
  "black") export bgc=40;;
  "red") export bgc=41;;
  "green") export bgc=42;;
  "yellow") export bgc=33;;
  "blue") export bgc=44;;
  "purple") export bgc=45;;
  "cyan") export bgc=46;;
  "white") export bgc=47;;
  "exit") exit;;
  *) echo "Invalid Choice"
    exit;;
 esac
 break
done

#PS1=$'[\e[0;'"$fgc;$bgc"'\u@\h:\w\$ \]'
PS1=$"\[\e[0;$fgc;"$bgc"m\u@\h:\w\$ \]"

results in the correct output. The script does need to be run with source or . in order to affect terminal settings.


All times are GMT -5. The time now is 04:59 PM.