#!/bin/bash # Purpose: A pretty GUI frontend to eselect, using zenity # Author: Donnie Berkholz # TODO: # Support additional types of eselect module besides single # Supported modules, and how they act # "single" is a single-choice type MODULES=( emacs:single esd:single opengl:single profile:single ) # Attempt to run a command # On failure, present an error message and return failure try() { local COMMAND=$@ OUTPUT=$(${COMMAND} 2>&1) && echo ${OUTPUT} && return 0 zenity \ --error \ --text=" Failed command: ${COMMAND} Output: ${OUTPUT}" return 1 } # Present a radio-button list for eselect modules that take a single choice # and show the active choice in the third field of 'list' output # Run the chosen eselect command do_choice_single() { local i=0 line MODULE=$1 ZENITY_OPTIONS declare -a E_OPTIONS while read line; do E_OPTIONS[i]=${line} (( i++ )) done < <(eselect --no-color ${MODULE} list | grep '\[[0-9]*\]') # Build options list local STATUS CHOICE declare -a E_OPTION_LINE for (( j=0; j<${#E_OPTIONS[@]}; j++ )); do set ${E_OPTIONS[j]} shift # If the selection's active if [[ ${!#} = \* ]]; then STATUS="TRUE" # Strip the '*' off the end set ${@:0:$(($#-1))} else STATUS="FALSE" fi ALL="$@" # Replace spaces with underscores for zenity # Hopefully no eselect output uses underscores ZENITY_OPTIONS="${ZENITY_OPTIONS} ${STATUS} ${ALL// /_}" done ZENITY_COMMAND="zenity \ --list --radiolist \ --column="choice" --column="${MODULE}" \ ${ZENITY_OPTIONS}" CHOICE=$(try ${ZENITY_COMMAND}) [[ $? -ne 0 ]] && return 1 # Restore underscores to spaces so we can match properly CHOICE=${CHOICE//_/ } local CHOICENUM for (( k=0; k<${#E_OPTIONS[@]}; k++ )); do # It's k+1 because eselect numbers start at 1, not 0 [[ ${E_OPTIONS[k]} = *${CHOICE}* ]] && CHOICENUM=$((k+1)) done try eselect ${MODULE} set ${CHOICENUM} } # Asks user to select an available module and runs it pick_module() { declare -a MODNAMES MODNAMES=${MODULES[@]/:*} local MOD ZENITY_OPTIONS for MOD in ${MODNAMES}; do # Make sure the module's installed, and it has selections available if eselect --no-color list-modules | grep -q "\<${MOD}\>" \ && eselect --no-color ${MOD} list | grep -q '\[[0-9]*\]'; then ZENITY_OPTIONS="${ZENITY_OPTIONS} FALSE ${MOD}" fi done local ZENITY_COMMAND="zenity \ --list --radiolist \ --column="choice" --column="module" \ ${ZENITY_OPTIONS}" local CHOICE=$(try ${ZENITY_COMMAND}) [[ $? -ne 0 ]] && return 1 # Find type, given a known module local MODULE for MODULE in ${MODULES[@]}; do MOD=${MODULE/:*} if [[ ${MOD} = ${CHOICE} ]]; then TYPE=${MODULE/*:} break fi done echo "Running do_choice_${TYPE} ${MOD}" do_choice_${TYPE} ${MOD} || return 1 } main() { if [[ ${UID} -ne 0 ]]; then zenity \ --error \ --text="You must run ${0##*/} as root." exit 1 fi # Keep asking till they don't want to do any more configuration while pick_module; do true done } # We need to match '*' because eselect uses that for active selections, # so turn off globbing set -o noglob main set +o noglob