Skip to content

Instantly share code, notes, and snippets.

@DennisLfromGA
Last active December 22, 2015 04:38
Show Gist options
  • Save DennisLfromGA/6418198 to your computer and use it in GitHub Desktop.
Save DennisLfromGA/6418198 to your computer and use it in GitHub Desktop.
A crouton tool to search and prompt for a Desktop Environment (I.E.) gnome, xbmc, xfce4, etc. in a specified chroot based upon the contents of the '(chroot)/etc/crouton/targets' file. Also allows checking the 'crouton' version and optionally updating all targets in a chroot.
#!/bin/sh
echo_e='/bin/echo -e'
#######################
## Declare Variables ##
#######################
APPLICATION="${0##*/}"
Chroot_loc=/usr/local/chroots
[ -d /var/crouton/chroots ] && Chroot_loc='/var/crouton/chroots'
[ ! -d "$Chroot_loc" ] && Chroot_loc=''
Chroot_par="$(dirname "${Chroot_loc}")"
Color='y'
Gry_text=''; Red_text=''; Grn_text=''; Yel_text=''
Vio_text=''; Pur_text=''; Blu_text=''; Wht_text=''; Nrm_text=''
Bkgrd='-b'; Bkmsg="(run in background)"; SFX=f # Bkgrd=''; Bkmsg=''
List=''; Targs=''
GO='';GOAGAIN=''; CrU=''; UP=''; key=''
CurrentCrVer=''; LatestCrVer=''; ChrootCrVer=''
DE=''; nDE=0; DE_choice=''; DENumber=''
CR=''; nCR=1; CR_choice=''; CRNumber=''
DEBUG=''
USAGE="
USAGE: $ ${APPLICATION} [options] [chroot_name]
A program to search and prompt for a Desktop Environment (I.E.) gnome, xbmc, xfce4, etc.
in a specified chroot based upon the contents of the '(chroot)/etc/crouton/targets' file.
Also allows checking the 'crouton' version and optionally updating all targets in a chroot.
Options:
-b Run the specified command in the background - Default
-f Run the specified command in the foreground - Default: background
-l List chroots in '$Chroot_loc' & exit
-t List a chroot's targets & exit - requires chroot name
-w No colors displayed, only black & white - Default: color
-c CHROOTS Directory the chroots are in - Default: ${Chroot_loc}
[-n] CHROOT Name of the chroot to enter - Default: only chroot or none if more than one
plus:
-h Help - print help and usage summary & exit
-H Help & History - print help and usage summary plus version history & exit
-v Version - print version number & exit
-V Version & History - print version number plus version history & exit
"
#FORMAT: ${APPLICATION} [-b] [-f] [-l] [-t] [-w] [-c chroots_directory] [-n] chroot_name
# VERSION format: date '+%Y%m%d%H%M%S'
VERSION='20140710150511'
VERHIST="\
$APPLICATION-20140710150511 : Added the option to check the APPLICATION name to see if
$APPLICATION-20140710150511 + it ends in 'f' which will then operate in foreground mode
$APPLICATION-20140515134853 : Changed xinit target to be added only when .xinitrc exists
$APPLICATION-20140319173413 : Added detection & implemtation of CROUTON partition
$APPLICATION-20140319173413 + also added 'elementary' DE/target
$APPLICATION-20140119153310 : Added Version tracking and version history options
$APPLICATION-20140114001139 : Added Version number and option"
# If the APPLICATION name ends in 'f' then operate in foreground mode
if [ ! ${APPLICATION%$SFX} = "${APPLICATION}" ]; then Bkgrd=''; Bkmsg=''; fi
#########################
#### FUNCTIONS START ####
#########################
Get_Args() {
while getopts bdDfltwhc:n:hHvV OPT
do
case ${OPT} in
b) Bkgrd='-b'; Bkmsg="(run in background)" ;;
d) DEBUG='y'
$echo_e "\n### ${Yel_text}DEBUG output selected${Nrm_text} ###" ;;
D) DEBUG=$(($DEBUG+1))
[ "$DEBUG" = '1' ] && $echo_e "\n### ${Yel_text}special DEBUG output selected${Nrm_text} ###"
[ "$DEBUG" = '2' ] && ($echo_e "### ${Yel_text}extra-special DEBUG output selected${Nrm_text} ###\n"; sleep 3) ;;
f) Bkgrd=''; Bkmsg='' ;;
l) List='y' ;;
t) Targs='y';;
w) Color='' ;;
c) Chroot_loc="`readlink -f "$OPTARG"`"
if [ ! -d "${Chroot_loc}" ]; then
error 3 "${Red_text}No chroots folder found at ${Chroot_loc} - exiting...${Nrm_text}"
else
Chroot_par=$(dirname "${Chroot_loc}")
fi ;;
n) Chroot="${OPTARG}"
if [ -d "${Chroot_loc}/${Chroot}" ]; then
Cname="${Chroot_loc}/${Chroot}"
else
error 3 "${Red_text}No chroot named '${Chroot}' found in '${Chroot_loc}' - exiting...${Nrm_text}"
fi ;;
h) error 0 "${USAGE}" ;;
H) error 0 "${USAGE}\n${VERHIST}" ;;
v) error 0 "${APPLICATION}-${VERSION}" ;;
V) error 0 "${APPLICATION}-${VERSION}\n${VERHIST}" ;;
\?) error 2 "${USAGE}" ;;
esac
done
shift "$((OPTIND-1))"
[ -n "$Color" ] && Gry_text="\e[01;30m"
[ -n "$Color" ] && Red_text="\e[01;31m"
[ -n "$Color" ] && Grn_text="\e[01;32m"
[ -n "$Color" ] && Yel_text="\e[01;33m"
[ -n "$Color" ] && Vio_text="\e[01;34m"
[ -n "$Color" ] && Pur_text="\e[01;35m"
[ -n "$Color" ] && Blu_text="\e[01;36m"
[ -n "$Color" ] && Wht_text="\e[01;37m"
[ -n "$Color" ] && Nrm_text="\e[0m"
#
[ "$DEBUG" = '1' ] && $echo_e "\n# ${Yel_text}'APPLICATION' is: '$APPLICATION'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}------------- is: ---------${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Bkgrd' is: '$Bkgrd'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Bkmsg' is: '$Bkmsg'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'DEBUG' is: '$DEBUG'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'List' is: '$List'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Targs' is: '$Targs'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Chroot' is: '$Chroot'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Chroot_loc' is: '$Chroot_loc'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Chroot_par' is: '$Chroot_par'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'USAGE' is: '$USAGE'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "\n# (${Wht_text}Press ENTER to continue${Nrm_text})${Nrm_text} #\b\c" && read key
[ "$DEBUG" = '2' ] && set -x
#
### If just listing chroots, do it and exit
if [ "${List}" = 'y' ]; then
$echo_e "Chroots: \c"
ls "${Chroot_loc}" 2>/dev/null ; $echo_e "\c"
error 0
fi
## Call next function ##
Get_Chroots $*
}
Get_Chroots() {
### Make a temporary file and auto-remove it when the script ends.
CRname="/tmp/${APPLICATION}.CR.$$"; touch ${CRname}
TRAP="rm -f '${CRname}';${TRAP}"
trap "${TRAP}" INT HUP 0
### Need a chroot listed if not using -n.
if [ $# = 0 ] && [ ! -n "${Chroot}" ]; then
Nbr=$(ls -1 "${Chroot_loc}" 2>/dev/null | wc -l)
if [ "$Nbr" = 0 ]; then
error 0 "${Red_text}Sorry, no chroots found in '${Chroot_loc}'${Nrm_text}"
elif [ "$Nbr" = 1 ]; then
Chroot=$(ls -1 "${Chroot_loc}" 2>/dev/null)
Cname="${Chroot_loc}/${Chroot}"
else
### Put them in a numbered file for selection
for CR in $(ls "${Chroot_loc}" 2>/dev/null)
do
echo "${nCR}) ${CR}" >> ${CRname}
nCR="$((${nCR} + 1))"
done
$echo_e "\nBelow are the Chroots found in '${Chroot_loc}' -\n"
cat "${CRname}" | sed 's/^/ /g'
$echo_e "\n${Wht_text}Please select a number from one of the above $((${nCR} - 1)) entries -"
$echo_e "Optionally enter an 'r' to restart the selections: [#,r] ${Nrm_text}'_'\b\b\c"; read CRNumber
if [ -z "${CRNumber}" ]; then error 0 "Okay, got nothin' so quitting anyway..."; fi
Chroot="$(grep ^${CRNumber}\) ${CRname} | cut -d ' ' -f2)"
if [ "${CRNumber}" = 'r' ]; then
echo "Okay, got an 'r' so restarting..."
rm -f "${CRname}"; exec $0
fi
if [ -z "${Chroot}" ]; then
error 1 "${Red_text}No selection made - Aborting...${Nrm_text}"
else
if [ -d "${Chroot_loc}/${Chroot}" ]; then
Cname="${Chroot_loc}/${Chroot}"
else
error 3 "${Red_text}No chroot named '${Chroot}' found in '${Chroot_loc}' - exiting...${Nrm_text}"
fi
fi
fi
fi
### Get the chroot specified on the command line, if given
if [ -z "${Chroot}" -a "${#}" -gt 0 ]; then
Chroot="${1}"
if [ -d "${Chroot_loc}/${Chroot}" ]; then
Cname="${Chroot_loc}/${Chroot}"
else
error 3 "${Red_text}No chroot named '${Chroot}' found in '${Chroot_loc}' - exiting...${Nrm_text}"
fi
elif [ -z "${Chroot}" ]; then
$echo_e "${Red_text}No chroot specified - see below...${Nrm_text}"
ls "${Chroot_loc}" 2>/dev/null
error 1 "\n${USAGE}"
fi
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'Chroot' is: '$Chroot'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'Cname' is: '$Cname'${Nrm_text}"
#
## Call next function ##
Chk_Targets
}
Chk_Targets() {
if [ -z "${Cname}/etc/crouton/targets" -o ! -f "${Cname}/etc/crouton/targets" ]; then
error 3 "${Red_text}No valid '$Chroot/etc/crouton/targets' file found - exiting...${Nrm_text}"
else
TargetsFile="${Cname}/etc/crouton/targets"
All_Targets="-t $(cat "${TargetsFile}" | sed "s/'//g")"
fi
if [ "${Targs}" = 'y' ]; then
$echo_e "\n${Chroot} targets: \c"
cat "${TargetsFile}"; $echo_e "\c"
error 0
fi
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'TargetsFile' is: '$TargetsFile'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'All_Targets' is: '$All_Targets'${Nrm_text}"
#
## Call next function ##
Get_Targets
}
Get_Targets() {
### Make a temporary file and auto-remove it when the script ends.
DEname="/tmp/${APPLICATION}.DE.$$"; touch ${DEname}
TRAP="rm -f '${DEname}';${TRAP}"
trap "${TRAP}" INT HUP 0
### Get the chroot's targets
DE_list=$(cat "${TargetsFile}" | sed "s/'//g" | sed 's/,/ /g')
passwd="$Cname/etc/passwd"
uid='1000'
USERNAME="`awk -F: '$3=='"$uid"'{print $1; exit}' "$passwd"`"
CHROOTHOME="$Cname/`awk -F: '$1=="'"$USERNAME"'"{print $6; exit}' "$passwd"`"
if [ -s $CHROOTHOME/.xinitrc ]; then
DE_list="update-all-targets enter-chroot ${DE_list} xinit quit"
else
DE_list="update-all-targets enter-chroot ${DE_list} quit"
fi
### Put them in a numbered file for selection
for DE in $(echo "${DE_list}")
do
if [ "$(echo "${DE}" | grep -e audio -e gtk-extra -e chrom -e celme -e core -e keyb -e touch -e vnc -e x11 -e extension)" ]; then
continue
else
echo "${nDE}) ${DE}" >> ${DEname}
nDE="$((${nDE} + 1))"
fi
done
$echo_e "\nBelow are the Desktop Environments found for '${Chroot}' -\n"
cat "${DEname}" | sed 's/^/ /g'
$echo_e "\n${Wht_text}Please select a number from one of the above ${nDE} entries -"
$echo_e "Optionally enter an 'r' to restart the selections: [#,r] ${Nrm_text}'_'\b\b\c"; read DENumber
if [ -z "${DENumber}" ]; then error 0 "Okay, got nothin' so quitting anyway..."; fi
DE_choice="$(grep ^${DENumber}\) ${DEname} | cut -d ' ' -f2)"
case "${DE_choice}" in
update*) Start_script='update' ;;
enter*) Start_script='enter-chroot'; Bkgrd='' Bkmsg='' ;;
cli*) Start_script='startcli'; Bkgrd='' Bkmsg='' ;;
e17) Start_script='starte17' ;;
cinn*) Start_script='startcinnamon' ;;
elem*) Start_script='startelementary' ;;
gnome) Start_script='startgnome' ;;
kde*) Start_script='startkde' ;;
lxde*) Start_script='startlxde' ;;
open*) Start_script='startob' ;;
unity*) Start_script='startunity' ;;
xbmc) Start_script='startxbmc' ;;
xfce*) Start_script='startxfce4' ;;
xinit) Start_script='startxi' ;;
quit) error 0 "Okay, quitting..." ;;
*) if [ "${DENumber}" = 'r' ]; then
echo "Okay, got an 'r' so restarting..."
rm -f "${CRname}" "${DEname}"; exec $0
elif [ "${DENumber}" = 'q' ]; then
error 0 "Okay, got a 'q' so quitting ..."
else
error 2 "Option '${DENumber}' not recognized - Aborting..."
fi ;;
esac
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'DE_list' is: '$DE_list'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'DE_choice' is: '$DE_choice'${Nrm_text}"
#
## Call next function ##
Set_Action
}
Set_Action() {
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'Start_script' is: '$Start_script'${Nrm_text}"
#
if [ "${Start_script}" = 'update' ]; then
## Call next function ##
Chk_Crouton $Chroot "$Cname"
$echo_e "\n${Gry_text}sudo sh -e ${Cr} -n ${Chroot} -p ${Chroot_par} -u${Nrm_text}"
$echo_e "${Wht_text}Enter 'y' to update '${Chroot}' - anything else to abort - ${Nrm_text}'_'\b\b\c"; read GO
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'GO' is: '$GO'${Nrm_text}"
#
if [ "${GO}" = 'r' -o "${GO}" = 'R' ]; then
rm ${CRname} ${DEname} 2>/dev/null && exec $0 ${Chroot}
fi
if [ "${GO}" = 'y' -o "${GO}" = 'Y' ]; then
if [ ! -s "${Chroot_par}/Cr-${Chroot}.log" ]; then
sudo touch "${Chroot_par}/Cr-${Chroot}.log"
sudo chmod 664 "${Chroot_par}/Cr-${Chroot}.log"
sudo chown root:chronos "${Chroot_par}/Cr-${Chroot}.log"
fi
$echo_e "\n# ${Yel_text}You can view the output of this update in ${Chroot_par}/Cr-${Chroot}.log${Nrm_text} #"; sleep 3
$echo_e "\n\n*** UPDATED - `date` ***\n${Cr} -p ${Chroot_par} -n ${Chroot} -u ***\n***\n" |\
sudo tee -a "${Chroot_par}/Cr-${Chroot}.log"
sudo sh -e "${Cr}" -n "${Chroot}" -p "${Chroot_par}" -u 2>&1 |\
sudo tee -a "${Chroot_par}/Cr-${Chroot}.log"
$echo_e "\n${Blu_text}The '${Chroot}' chroot has been updated.${Nrm_text}"
$echo_e "${Wht_text}Enter 'y' to restart - anything else to quit - ${Nrm_text}'_'\b\b\c"; read GOAGAIN
if [ "${GOAGAIN}" = 'y' -o "${GOAGAIN}" = 'Y' ]; then
rm ${CRname} ${DEname} 2>/dev/null && exec $0 ${Chroot}
fi
else
error 0 "Okay, ABORTING ..."
fi
else
$echo_e "\n${Gry_text}sudo ${Start_script} -n ${Chroot} -c ${Chroot_loc} ${Bkgrd} ${Bkmsg}${Nrm_text}"
oldtrap="$TRAP"; trap - INT
$echo_e "${Wht_text}Executing in 5 seconds - Press 'Ctrl-C' TO ABORT! ${Nrm_text}'_'\b\b\c"; sleep 5
# read -t 5 -p "Executing in 5 seconds - ENTER 'a' TO ABORT! " GO
if [ -n "${GO}" ]; then error 0 "Okay, ABORTING ..."; fi
TRAP="$oldtrap"; trap "${TRAP}" INT HUP 0
sudo "${Start_script}" -n "${Chroot}" -c "${Chroot_loc}" ${Bkgrd}
fi
}
Chk_Crouton() {
### Ask if you want to check for updates
$echo_e "\n${Wht_text}Do you want to check for a newer version of 'crouton'"
$echo_e "before we update-all-targets for '${Chroot}' ? (Y/n) ${Nrm_text}'_'\b\b\c"; read CrU
if [ -n "${CrU}" -a "${CrU}" = 'n' ]; then
$echo_e "\n${Blu_text}Okay, no version check of crouton will be done...${Nrm_text}"
else
### Download latest version of 'crouton' & report it
LatestCr='/tmp/crouton.latest'; sudo rm $LatestCr >/dev/null 2>&1
"${Cname}/usr/local/bin/croutonversion" -duf $LatestCr >/dev/null 2>&1
if [ ! -r $LatestCr ]; then wget -qO $LatestCr http://goo.gl/fd3zc; fi
LatestCrVer=$(sh $LatestCr -V | cut -d' ' -f3 | sed "s/'//g")
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'LatestCrVer' is: '$LatestCrVer'${Nrm_text}"
#
$echo_e "\n${Yel_text}The latest version of 'crouton' is: ${LatestCrVer}${Nrm_text}"
### Attempt to find a local version of 'crouton' & report it
if [ -r "${Chroot_par}/bin/crouton" ]; then Cr="${Chroot_par}/bin/crouton"
elif [ -r /usr/local/bin/crouton ]; then Cr=/usr/local/bin/crouton
elif [ -r $HOME/Downloads/crouton ]; then Cr=$HOME/Downloads/crouton
else Cr=$(which crouton 2>/dev/null)
fi
### Notify that if one wasn't found, one will be put in Downloads
if [ -s "${Cr}" ]; then
CrFound='y'
CurrentCrVer=$(sh "$Cr" -V | cut -d' ' -f3 | sed "s/'//g")
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'Cr' is: '$Cr'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'CurrentCrVer' is: '$CurrentCrVer'${Nrm_text}\n"
#
$echo_e "${Blu_text}The local version of 'crouton' is: ${CurrentCrVer}${Nrm_text}"
else
CrFound='n'
$echo_e "\n'crouton' is not in your Downloads folder or \$PATH ..."
$echo_e "${Blu_text}Installing the latest version in '$HOME/Downloads'${Nrm_text}"
Cr="$HOME/Downloads/crouton"
sudo cp -f "$LatestCr" "$Cr" && sudo chmod +x "${Cr}"
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'Cr' is: '$Cr'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'CurrentCrVer' is: 'NULL'${Nrm_text}\n"
#
fi
### Get the chroot's version of 'crouton' when installed or updated & report it
ChrootCrVer=$(grep '^VERSION=' "${Cname}/usr/local/bin/croutonversion" | cut -d= -f2 | sed "s/'//g")
if [ -z "$ChrootCrVer" ]; then ChrootCrVer='* NULL *'; fi
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'ChrootCrVer' is: '$ChrootCrVer'${Nrm_text}\n"
#
$echo_e "${Blu_text}The '$Chroot' version of 'crouton' is: ${ChrootCrVer}${Nrm_text}"
### Now compare local crouton version with the latest
if [ "$CrFound" = 'y' ]; then
if [ "$LatestCrVer" = "$CurrentCrVer" ]; then
$echo_e "\n${Grn_text}Your local 'crouton' version is the latest - that's good.${Nrm_text}"
else
$echo_e "\n${Red_text}Your local 'crouton' version is NOT the latest!${Nrm_text}"
$echo_e "${Wht_text}Shall we update 'crouton' now ? (Y/n) ${Nrm_text}'_'\b\b\c"; read UP
if [ -n "${UP}" -a "${UP}" = 'n' ]; then
echo "Okay, skipping update ..."
else
$echo_e "${Blu_text}Installing the latest version in '`dirname "$Cr"`'${Nrm_text}"
sudo mv -f "${Cr}" "${Cr}.bak"
sudo cp -f "$LatestCr" "$Cr" && sudo chmod +x "${Cr}"
fi
fi
fi
### Now compare local chroot version with the latest
if [ "$LatestCrVer" = "$ChrootCrVer" ]; then
$echo_e "\n${Grn_text}Your local '${Chroot}' version is the latest - that's good.${Nrm_text}"
echo "You can safely elect to not update it when asked next."
else
$echo_e "\n${Red_text}Your local '${Chroot}' version is NOT the latest!${Nrm_text}"
echo "You can elect to update it when asked next."
fi
fi
}
### exit with exit code $1, spitting out message $@ to stderr
error() {
local ecode="${1}"
shift
$echo_e "${*}" 1>&2
exit "${ecode}"
}
#########################
#### FUNCTIONS END ####
#########################
Get_Args $*
[ "$DEBUG" = '2' ] && set +x
@DennisLfromGA
Copy link
Author

Changed script to add a color output by default, color can be turned off with the '-w' option.
The original non-color script has been renamed to 'startcr.b+w' and is no longer ...

@DennisLfromGA
Copy link
Author

Added Version tracking and version history options. Also added detection & implemtation of CROUTON partition, plus added 'elementary' DE/target

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment