Reading and Writing a conf file - Suggestions and improvements?

Hello all

As part of my TUI - (line based) Text User Interface, i do have 2 commands to assist working with conf files.
Now, for me they work, but since i wrote them, i automaticly use them they way they should be used... you know what i mean. :wink:

Anyway, they are designed to read 'simple' values, such as words or numbers, maybe a sentence.
However, if there is a 'variable' saved, it shows them, and upon saving it saves it 'as is'.

But this leads to 'shell injection', which i certainly want to avoid here, as i only want the values to be saved or read as is.

The usage is quite simple:
to get a list:

:) ~ $ tui-conf-get -l /etc/default/grub
GRUB_TIMEOUT
GRUB_DISTRIBUTOR
GRUB_DEFAULT
GRUB_DISABLE_SUBMENU
GRUB_TERMINAL_OUTPUT
GRUB_CMDLINE_LINUX
GRUB_DISABLE_RECOVERY
GRUB_THEME
GRUB_GFXMODE
GRUB_GFXPAYLOAD_LINUX

Read a value:

 ~ $ tui-conf-get /etc/default/grub GRUB_CMDLINE_LINUX
rd.luks.uuid luks-<guid-string> vconsole.font latarcyrheb-sun16 rd.luks.uuid luks-<guid-string> $([ -x /usr/sbin/rhcrashkernel-param ] && /usr/sbin/rhcrashkernel-param || :) ~ $ 

or

+ ~ $ tui-conf-get /etc/default/grub GRUB_THEME
/boot/grub2/themes/circled-nasa-horizon/theme.txt:) ~ $ 

Write a value:

 ~ $ sudo tui-conf-set /etc/default/grub GRUB_THEME /boot/grub2/themes/circled-nasa-capsule/theme.txt
:) ~ $ tui-conf-get /etc/default/grub GRUB_THEME
/boot/grub2/themes/circled-nasa-capsule/theme.txt+ ~ $

The 'core' of tui-conf-get:

...
	[[ -z "$2" ]] && printf "$help_text" && exit $RET_HELP
	while getopts "ilh" name
	do 	case $name in
		i)	OPT="-i"
			;;
		l)	grep -v ^# "$2"|grep "="|sed s,"="," ",g|awk '{print $1}'
			exit 0
			;;
		h)	printf "$help_text"
			exit $RET_HELP
			;;
		esac
	done
	shift $(($OPTIND - 1))
	CONFFILE="$1"
	VARNAME="$2"
	[[ ! -f "$CONFFILE" ]]  && echo "$CONFFILE dont exist?" "$TUI_FAIL" && exit 1
#
#	Display & Action
#
	VALUE=$(grep $OPT "${VARNAME}=" "$CONFFILE"|grep -v ^#|sed s,'"','',g|sed s,'=',' ',g) > /dev/zero
	VALUE="${VALUE:${#VARNAME}+1}"
	printf "$VALUE"

The core of tui-conf-set is a bit more complex, as i want to preserve existing quotes of the value, without the user needing to add them again. Also there is specialy handling according to chars within the value-string to be saved, if there is a coma, back-/slash, whatsoever, and change the Sed-Divider (SD) accordingly.

#
# 	Preformat strings
#
	SEARCH="$(grep $OPT "${VARNAME}=" "$CONFFILE"|grep -v ^#|tr -d [:space:])"
	$SMALL && VARNAME="${VARNAME,,}"
	$CAPS  && VARNAME="${VARNAME^^}"
	printf  "$SEARCH"|grep -q "\"" && \
		REPLACE="$VARNAME=\"$VALUE\"" || \
		REPLACE="$VARNAME=$VALUE"
	# Set proper SED 'divider'
	SD=","
	if echo "$REPLACE"|grep -q "$SD"
	then 	# Coma was found
		SD="/"
		printf "$REPLACE"|grep ","|grep "$SD"|grep -q '\\' && SD="\\"	# backslash was found
		[[ ! "$SD" = "/" ]] && \
			printf "$REPLACE"|grep ","|grep "$SD"|grep -q "/" && SD="|"	# Forward slash was found
	fi
	# Troubles with VARIABLES due to leading '$'
	printf "$SEARCH"|grep -q "\$" && \
		SEARCH="$(printf "$SEARCH"|sed s,'\$','\\\$',g)" && \
		hadDollar=true
	# FORUM EDIT: This was required to escape dollar signes, so they are not 'executed' or read
#
#	Display & Action
#
	# Generate the command
	cmd="$(which sed) s${SD}'${SEARCH}'${SD}'${REPLACE}'${SD}g -i \"$CONFFILE\""
	# Save changes
	if ! grep -q "$VARNAME" "$CONFFILE"
	then	# Its not there yet, just append it
		printf "${REPLACE}\n" >> "$CONFFILE"
	elif $hadDollar
	then	# FORUM EDIT: This is required to remove the escaped dollar signed, so the dollar sign is saved and not its (the variables) value.
	eval "$cmd"
	else	$cmd
	fi
	#
	# Return true if replaced string was found
	# This is required, since using RET=$? returned true eventhough value was not saved...
	grep -q "$REPLACE" "$CONFFILE"

Any suggestions?

To be complete, i add the full scripts as attachments, and inform you that to use sudo tui-conf-set CONFIG VARIABLE VALUE tui-conf-set must be located in either /bin or /sbin, $HOME/bin will not work unless you use: sudo $(which tui-conf-set)
As they are part of a package, they originaly do not have the .sh extension, that has been added to attach them here.

Thank you in advance

1 Like

Hey

I hope I'm not completely missing the point here. :slight_smile:
It seems there is a lot of searching for characters that need to be escaped, and changing the SD because of file content.

In that case, it might save some work to decide what you want to use for the SD, say '|', and include it in a group of others you want to escape, such as $,/". etc.

Sed has a character '&' which stands for "what was found". You could use it something like this and do all your escaping in one go, and not have to change the SD so much:

sed 's|["$/\|\@]|\\&|g'

Am I even close to what you need?

1 Like

Yes, sorry i guess this one belongs to the cathegory of 'unclear description'.

Its exactly what i needed!
And finaly figured why it did fail on some values but not on others while trying to get it working...
i had removed spaces... bad idea... :doh:

But you mix the both... the variable i use as SED-DIVIDER is required, because even with ' strings, it fails if there is the same char within any part of the strings to work with.
But thanks to your saying i had another look and could shorten it a little.

EDIT:
Updated attached file tui-conf-set.sh.

Pretty good.
You've put together a lot of utilities. Haven't had time to try them all but liking what I see. It's a little scary at first, but it shure cuts down on all the comments and clutter.

Cheers

1 Like