在 /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 的字段中),它需要包含合并逻辑 - 要么附加新的配置记录,要么更新现有的配置记录。最重要的是,它应该防止文件看起来像这样:(由经验丰富的 shell 脚本编写者在每次调用时调用 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
谢谢, 格言。
-- 更新:我实际上有点喜欢这个脚本,所以我对其进行了一些改进。现在似乎已经准备好生产了。享受。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以在
/etc/profile.d/
中创建一个具有您自己名称的文件,而不是尝试解析/etc/environment
文件,正如我在 我对相关问题的回答 。然后您可以在安装过程中复制它,因为它只包含您的内容。更不用说它会让你的脚本变得更短。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.如果在文件中找到该模式,
grep
命令将返回 0 (true)。所以,上面的内容是:检查文件中是否设置了 JAVA_HOME
或者在文件中设置 JAVA_HOME
如您所见,如果您多次调用此单行代码,则后续调用不会添加到文件中,因为 grep 在您尝试追加文件之前返回 true。
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
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.
在我的 Ubuntu 系统中,我的 JAVA_HOME 看起来像这样:
用 ls -l /usr/lib/jvm/default-java 查看该文件我注意到了这一点:
换句话说,软链接中的路径这是你唯一需要改变的事情。
要查看已安装的 Java 环境列表,我使用了
ls -l ...
命令:现在我可以使用以下命令切换到另一个默认值:
JAVA_HOME 变量将从 Oracle 运行 Java 7。
In my Ubuntu system, my JAVA_HOME looks like this:
Looking at that file with
ls -l /usr/lib/jvm/default-java
I noticed this:In other words, the path in the soft link is the only thing you have to change.
To see the list of installed Java environments, I used this
ls -l ...
command:So now I can switch to another default with:
And the JAVA_HOME variable will run Java 7 from Oracle.