Add or update a configuration record in /etc/environment
Solution 1
Instead of trying to parse /etc/environment
file, you could instead create a file with your own name in /etc/profile.d/
, as I described in my answer to a relevant question. Then you could just copy it over during installation, because it contains just your content. Let alone that it will make your scripts shorter.
Solution 2
grep -q JAVA_HOME /etc/environment || echo 'JAVA_HOME="/usr/lib/jvm/java-5-sun"' >> /etc/environment
The grep
command returns 0 (true) if the pattern is found in the file. So, the above reads:
check if JAVA_HOME is set in the file
OR set JAVA_HOME in the file
0-15:49 root@noneedto ~# cat /etc/environment PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" 0-15:49 root@noneedto ~# grep JAVA_HOME /etc/environment && echo true 1-15:49 root@noneedto ~# grep -q JAVA_HOME /etc/environment || echo 'JAVA_HOME="/usr/lib/jvm/java-5-sun"' >> /etc/environment 0-15:49 root@noneedto ~# grep JAVA_HOME /etc/environment && echo true JAVA_HOME="/usr/lib/jvm/java-5-sun" true 0-15:49 root@noneedto ~# grep -q JAVA_HOME /etc/environment || echo 'JAVA_HOME="/usr/lib/jvm/java-5-sun"' >> /etc/environment 0-15:49 root@noneedto ~# cat /etc/environment PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" JAVA_HOME="/usr/lib/jvm/java-5-sun"
As you can see, if you invoke this one-liner multiple times, subsequent invocations do not add to the file because grep returns true before you attempt to append the file.
Comments
-
Maxim Veksler about 4 years
My /etc/environment looks like this:
cat /etc/environment PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
I wish to use a command (sed, awk, python, whatever....) that will make it look like this:
cat /etc/environment PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" JAVA_HOME="/usr/lib/jvm/java-6-sun"
Now the catch is, I would rather it be a 1 liner (in the fields of sed -XYZ /DoMagic/ /etc/environment), it needs to contain merging logic that is - either appends a new configuration record or update an existing one. Bottom line, it should prevent the file from looking like this: (Caused by in experienced shell scripters calling echo >> on each invocation)
cat /etc/environment PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" JAVA_HOME="/usr/lib/jvm/java-5-sun" JAVA_HOME="/usr/lib/jvm/java-6-sun" JAVA_HOME="/usr/lib/jvm/java-6-sun" JAVA_HOME="/usr/lib/jvm/java-6-sun"
I guess this is a trick questions, because what I'm trying to avoid using custom scripts, such as
/usr/local/bin/PropUpdate /etc/environment JAVA_HOME "/usr/lib/jvm/java-6-sun"
/usr/local/bin/PropUpdate is the following script (written for the sake of example, may contain bugs. Comments are appreciated)
#!/bin/bash # Append/Update a configuration record in a file # # Usage example: # /usr/local/bin/PropUpdate /etc/environment JAVA_HOME "/usr/lib/jvm/java-6-sun" # # Author Maxim Veksler <[email protected]> # Version 0.5-2010-07-27 EXPECTED_ARGS=3 E_BADARGS=3 E_BADFILE=4 if [[ $# -ne ${EXPECTED_ARGS} ]]; then echo "Usage: `basename $0` /path/to/config.conf ParameterName newValueText" >&2 exit $E_BADARGS fi CONFIGURATION_FILE="$1" CONFIGURATION_PARAMETER="$2" CONFIGURATION_VALUE="$3" if [[ ! -e "${CONFIGURATION_FILE}" ]]; then echo "Configuration file ${CONFIGURATION_FILE} does not exist" >&2 exit $E_BADFILE fi if [[ ! -w "${CONFIGURATION_FILE}" ]]; then echo "Can't modify ${CONFIGURATION_FILE}" >&2 exit $E_BADFILE fi ######################################### ## Decide what parameter we are adding ## ######################################### __param_found=0 # First check CONFIGURATION_PARAMETER supplied by use that contains "=" if [[ ${CONFIGURATION_PARAMETER} == *=* ]]; then # It should exist in the file, plain if grep -qE "^${CONFIGURATION_PARAMETER}" "${CONFIGURATION_FILE}"; then __param_found=1 SUFFIX_REGEX='[[:space:]]*' fi else # OK, sophisticated user, did not send "=" with the parameter... if grep -qE "^${CONFIGURATION_PARAMETER}[[:space:]]*=" "${CONFIGURATION_FILE}"; then # Let's check if such configuration with Parameter + "=" exists __param_found=1 SUFFIX_REGEX='[[:space:]]*=[[:space:]]*' elif grep -qE "^${CONFIGURATION_PARAMETER}[[:space:]]+" "${CONFIGURATION_FILE}"; then # If such parameter exists, at all __param_found=1 SUFFIX_REGEX='[[:space:]]\+' fi fi if [[ $__param_found == 1 ]]; then #echo sed -i "s|^\(${CONFIGURATION_PARAMETER}${SUFFIX_REGEX}\).*$|\1${CONFIGURATION_VALUE}|g" "${CONFIGURATION_FILE}" sed -i "s|^\(${CONFIGURATION_PARAMETER}${SUFFIX_REGEX}\).*$|\1${CONFIGURATION_VALUE}|g" "${CONFIGURATION_FILE}" else if [[ ${CONFIGURATION_PARAMETER} == *=* ]]; then # Configuration parameter contains "=" in it's name, good just append echo "${CONFIGURATION_PARAMETER}${CONFIGURATION_VALUE}" >> "${CONFIGURATION_FILE}" else # Try to guess if this file is a "param = value" or "param value" type of file. if grep -qE "^[[:alnum:]]+[[:space:]]*=" "${CONFIGURATION_FILE}"; then # Seems like a "param = value" type of file echo "${CONFIGURATION_PARAMETER}=${CONFIGURATION_VALUE}" >> "${CONFIGURATION_FILE}" else # Seems like a "param value" type of file echo "${CONFIGURATION_PARAMETER} ${CONFIGURATION_VALUE}" >> "${CONFIGURATION_FILE}" fi fi fi #cat $CONFIGURATION_FILE
Thank you, Maxim.
-- Update: I actually kinda liked this script, so I've improved it a bit. It now seems to be production ready. Enjoy.