Добавьте или обновите запись конфигурации в /etc/environment

Мой /etc/environment выглядит так:

cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"

Я хочу использовать команду (sed, awk, python, что угодно....), которая будет выглядеть так:

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"

Теперь загвоздка в том, что я бы предпочел, чтобы это был 1 лайнер (в полях sed -XYZ /DoMagic/ /etc/environment), он должен содержать логику слияния, то есть либо добавляет новую запись конфигурации, либо обновляет существующую. . В итоге файл должен выглядеть следующим образом: (Вызвано тем, что опытные сценарии оболочки вызывают echo >> при каждом вызове)

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"

Я предполагаю, что это вопросы с подвохом, потому что я пытаюсь избежать использования пользовательских сценариев, таких как

/usr/local/bin/PropUpdate /etc/environment JAVA_HOME "/usr/lib/jvm/java-6-sun"

/usr/local/bin/PropUpdate — это следующий скрипт (написан для примера, может содержать ошибки. Комментарии приветствуются)

#!/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

Спасибо, Максим.

-- Обновление: мне действительно понравился этот скрипт, поэтому я немного его улучшил. Теперь он, кажется, готов к производству. Наслаждаться.


person Maxim Veksler    schedule 25.07.2010    source источник
comment
@Zoredache, пожалуйста, напишите это как ответ, чтобы я мог его принять. Это инструмент, который я искал.   -  person Maxim Veksler    schedule 01.05.2012


Ответы (3)


Вместо того, чтобы пытаться анализировать файл /etc/environment, вы могли бы вместо этого создать файл со своим именем в /etc/profile.d/, как я описал в мой ответ на соответствующий вопрос. Тогда вы можете просто скопировать его во время установки, потому что он содержит только ваш контент. Не говоря уже о том, что это сделает ваши сценарии короче.

person P Shved    schedule 25.07.2010
comment
Спасибо, но я говорю об общей идее редактирования файлов конфигурации. Многие задействованные системы не реализуют шаблон проектирования rc*.d. - person Maxim Veksler; 26.07.2010

grep -q JAVA_HOME /etc/environment || echo 'JAVA_HOME="/usr/lib/jvm/java-5-sun"' >> /etc/environment

Команда grep возвращает 0 (истина), если шаблон найден в файле. Итак, выше написано:

проверьте, установлен ли JAVA_HOME в файле
ИЛИ установите JAVA_HOME в файле

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"

Как видите, если вы вызываете эту однострочную строку несколько раз, последующие вызовы не добавляются к файлу, потому что grep возвращает true до того, как вы попытаетесь добавить файл.

person Community    schedule 26.07.2010
comment
Да, а как насчет обновления файла? Скажем, я хочу заменить JAVA_HOME=/usr/lib/jvm/java-5-sun на JAVA_HOME=/usr/lib/jvm/java-6-sun. Здесь начинается настоящая проблема. - person Maxim Veksler; 27.07.2010
comment
Или вы могли бы grep -q 'JAVA_HOME="/usr/lib/jvm/java-6-sun"' . . . со сценариями оболочки и множеством файлов конфигурации последнее определение стирает все предыдущие определения. Либо вы бы предпочли, чтобы это был 1 лайнер, как вы указали в своем вопросе, и в этом случае вы оцениваете код возврата из grep, либо вам действительно нужна обобщенная система управления конфигурацией, подобная той, что предлагается cfengine или puppet. (Я чертовски уверен, что Ubuntu справляется с этими обыденными деталями конфигурации, как и должно быть.) - person dannyman; 28.07.2010

В моей системе Ubuntu мой JAVA_HOME выглядит так:

JAVA_HOME=/usr/lib/jvm/default-java

Глядя на этот файл с ls -l /usr/lib/jvm/default-java я заметил это:

lrwxrwxrwx 1 root root 24 Apr 27  2012 /usr/lib/jvm/default-java -> java-1.7.0-openjdk-amd64

Другими словами, путь в программной ссылке — это единственное, что вам нужно изменить.

Чтобы просмотреть список установленных сред Java, я использовал эту команду ls -l ...:

prompt$ ls -l /usr/lib/jvm
total 20
lrwxrwxrwx 1 root root   24 Apr 27  2012 default-java -> java-1.7.0-openjdk-amd64
drwxr-xr-x 4 root root 4096 Feb 23 17:54 java-1.5.0-gcj-4.8-amd64
lrwxrwxrwx 1 root root   20 Sep  2  2012 java-1.6.0-openjdk-amd64 -> java-6-openjdk-amd64
lrwxrwxrwx 1 root root   20 Jul  3  2013 java-1.7.0-openjdk-amd64 -> java-7-openjdk-amd64
drwxr-xr-x 5 root root 4096 Oct  7  2012 java-6-openjdk-amd64
drwxr-xr-x 3 root root 4096 Oct  7  2012 java-6-openjdk-common
drwxr-xr-x 5 root root 4096 Sep 21 20:06 java-7-openjdk-amd64
drwxr-xr-x 8 root root 4096 Sep 18 21:18 java-7-oracle

Итак, теперь я могу переключиться на другое значение по умолчанию:

sudo rm /usr/lib/jvm/default-java
sudo ln -s java-7-oracle /usr/lib/jvm/default-java

А переменная JAVA_HOME запустит Java 7 из Oracle.

person Alexis Wilke    schedule 25.02.2014