Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用bash脚本修改配置文件_Bash_Configuration Files - Fatal编程技术网

使用bash脚本修改配置文件

使用bash脚本修改配置文件,bash,configuration-files,Bash,Configuration Files,我正在编写一个bash脚本来修改包含一组键/值对的配置文件。如何读取密钥并找到值并可能对其进行修改?假设您的配置文件的格式如下: CONFIG_NUM=4 CONFIG_NUM2=5 CONFIG_DEBUG=n 在bash脚本中,可以使用: CONFIG_FILE=your_config_file . $CONFIG_FILE if [ $CONFIG_DEBUG == "y" ]; then ...... else ...... fi $CONFIG\u NUM,$CO

我正在编写一个bash脚本来修改包含一组键/值对的配置文件。如何读取密钥并找到值并可能对其进行修改?

假设您的配置文件的格式如下:

CONFIG_NUM=4
CONFIG_NUM2=5
CONFIG_DEBUG=n
在bash脚本中,可以使用:

CONFIG_FILE=your_config_file
. $CONFIG_FILE

if [ $CONFIG_DEBUG == "y" ]; then
    ......
else
    ......
fi
$CONFIG\u NUM
$CONFIG\u NUM2
$CONFIG\u DEBUG
是您所需要的

读取值后,将其写回将很容易:

echo "CONFIG_DEBUG=y" >> $CONFIG_FILE

在黑暗中修改单个值的疯狂尝试:

sed -c -i "s/\($TARGET_KEY *= *\).*/\1$REPLACEMENT_VALUE/" $CONFIG_FILE
假设目标键和替换值不包含任何特殊的正则表达式字符,并且键值分隔符为“=”。注意,-c选项依赖于系统,您可能需要省略它,以便sed执行


有关如何进行类似替换的其他提示(例如,当替换值中包含“/”字符时),

一般来说,使用grep和cut提取信息很容易:


cat "$FILE" | grep "^${KEY}${DELIMITER}" | cut -f2- -d"$DELIMITER"
要更新,您可以执行以下操作:


mv "$FILE" "$FILE.bak"
cat "$FILE.bak" | grep -v "^${KEY}${DELIMITER}" > "$FILE"
echo "${KEY}${DELIMITER}${NEWVALUE}" >> "$FILE"

这显然不能维持键值对的顺序。添加错误检查以确保不会丢失数据。

假设您有一个包含
key=value
对的文件,在
=
周围可能有空格,您可以使用
awk
随意删除、修改或追加键值对,即使这些键值或值包含特殊的正则表达式序列:

# Using awk to delete, modify or append keys
# In case of an error the original configuration file is left intact
# Also leaves a timestamped backup copy (omit the cp -p if none is required)
CONFIG_FILE=file.conf
cp -p "$CONFIG_FILE" "$CONFIG_FILE.orig.`date \"+%Y%m%d_%H%M%S\"`" &&
awk -F '[ \t]*=[ \t]*' '$1=="keytodelete" { next } $1=="keytomodify" { print "keytomodify=newvalue" ; next } { print } END { print "keytoappend=value" }' "$CONFIG_FILE" >"$CONFIG_FILE~" &&
mv "$CONFIG_FILE~" "$CONFIG_FILE" ||
echo "an error has occurred (permissions? disk space?)"

希望这对别人有帮助。我创建了一个自包含脚本,它需要各种配置处理

#!/bin/bash
CONFIG="/tmp/test.cfg"

# Use this to set the new config value, needs 2 parameters. 
# You could check that $1 and $2 is set, but I am lazy
function set_config(){
    sudo sed -i "s/^\($1\s*=\s*\).*\$/\1$2/" $CONFIG
}

# INITIALIZE CONFIG IF IT'S MISSING
if [ ! -e "${CONFIG}" ] ; then
    # Set default variable value
    sudo touch $CONFIG
    echo "myname=\"Test\"" | sudo tee --append $CONFIG
fi

# LOAD THE CONFIG FILE
source $CONFIG

echo "${myname}" # SHOULD OUTPUT DEFAULT (test) ON FIRST RUN
myname="Erl"
echo "${myname}" # SHOULD OUTPUT Erl
set_config myname $myname # SETS THE NEW VALUE

因此,我不能对此加以赞扬,因为这是stackoverflow答案和来自irc.freenode.net#bash通道的帮助的组合,但下面是用于设置和读取配置文件值的bash函数:

#https://stackoverflow.com/a/2464883
#用法:config_设置文件名键值
函数配置_集(){
本地文件=$1
本地密钥=$2
本地val=${@:3}
ensureConfigFileExists“${file}”
#如果不存在,则创建密钥
如果!grep-q“^${key}=“${file};那么
#插入换行符,以防文件未以换行符结尾
printf“\n${key}=“>>${file}”
fi
chc“$file”$key“$val”
}
函数ensureConfigFileExists(){
如果[!-e“$1”];则
如果[-e“$1.示例”];则
cp“$1.示例”$1”;
其他的
触摸“$1”
fi
fi
}
#感谢irc.freenode.net上的ixz in#bash
函数chc(){gawk-vofs===-vfs==-e'开始{ARGC=1}$1==ARGV[2]{print ARGV[4]?ARGV[4]:$1,ARGV[3];下一个}1'$@“$1.1”;mv“$1”{.1,};}
# https://unix.stackexchange.com/a/331965/312709
#用法:local myvar=“$(config\u get myvar)”
函数config_get(){
val=“$(配置读取文件${配置文件}”${1}”);
如果[“${val}”=“\uuuu未定义”];则
val=“$(config_read_file${config_file}。示例“${1}”);
fi
printf--“%s”“${val}”;
}
函数配置\读取\文件(){
(grep-E“^${2}=“-m1”${1}”2>/dev/null | | | echo”VAR=|u未定义|”)| head-n1 | cut-d'='-f2-;
}
起初,我使用的是公认答案的sed解决方案:


但是,如果该值有一个/char,它会断开

,不会替换该值,只需在底部再次添加它,它完全取决于配置文件是否是有效的bash脚本,并且。。。哇,如果配置文件中有恶意内容呢?如果磁盘空间不足,或者由于任何原因无法创建
文件
,那么您的解决方案将丢失
文件
(必须手动将
文件重命名为
文件.bak
以恢复)。-c在我的环境中似乎无效。当我去掉-c时,它就起作用了。谢谢。这个答案我真的投了两张反对票吗?我不仅成功地猜出了OP想要什么,而且它又短又高效。有人想解释一下吗?@prolink:
ssh[opts][user@]hostname命令将登录,然后运行给定的命令。如果该命令足够复杂,您可能希望将其存储在远程服务器上的脚本中,以便只运行
ssh path/to/script
。如果有人在Mac环境中执行该命令,您可能希望删除-c并在-i之后添加“”。就像
sed-i''s…“$CONFIG_文件
非常有用的脚本一样。如果所有的键都在行的开头开始,考虑在<代码> $TAGTIGKEY键/代码>之前添加<代码> ^ < /代码>,否则,如果你有两个键,如<代码>偶数=2 和<代码> NoDeNo>=1 < /代码>,你将最终改变这两个键。我试图回答这个问题,我怀疑这是否适用于TUNL,甚至YAML或JSON,因为它们有部分。不过,它只适用于键值对
#!/bin/bash
CONFIG="/tmp/test.cfg"

# Use this to set the new config value, needs 2 parameters. 
# You could check that $1 and $2 is set, but I am lazy
function set_config(){
    sudo sed -i "s/^\($1\s*=\s*\).*\$/\1$2/" $CONFIG
}

# INITIALIZE CONFIG IF IT'S MISSING
if [ ! -e "${CONFIG}" ] ; then
    # Set default variable value
    sudo touch $CONFIG
    echo "myname=\"Test\"" | sudo tee --append $CONFIG
fi

# LOAD THE CONFIG FILE
source $CONFIG

echo "${myname}" # SHOULD OUTPUT DEFAULT (test) ON FIRST RUN
myname="Erl"
echo "${myname}" # SHOULD OUTPUT Erl
set_config myname $myname # SETS THE NEW VALUE