내 웹 서버의 Apache 및 PHP 구성 파일 작성을 자동화하는 스크립트를 작성 중입니다. CPanel 또는 ISPConfig와 같은 GUI를 사용하고 싶지 않습니다.
Apache 및 PHP 구성 파일의 템플릿이 있습니다. Bash 스크립트는 템플릿을 읽고 변수를 대체하며 구문 분석 된 템플릿을 일부 폴더에 출력해야합니다. 가장 좋은 방법은 무엇입니까? 몇 가지 방법을 생각할 수 있습니다. 어느 것이 가장 좋거나 더 좋은 방법이 있습니까? 순수한 Bash에서 그렇게하고 싶습니다 (예를 들어 PHP에서는 쉽습니다)
1) 텍스트 파일에서 $ {} 자리 표시자를 바꾸는 방법은 무엇입니까?
template.txt :
the number is ${i}
the word is ${word}
script.sh :
#!/bin/sh
#set variables
i=1
word="dog"
#read in template one line at the time, and replace variables
#(more natural (and efficient) way, thanks to Jonathan Leffler)
while read line
do
eval echo "$line"
done < "./template.txt"
BTW, 출력을 외부 파일로 어떻게 리디렉션합니까? 변수에 따옴표가 포함되어 있으면 무언가를 피해야합니까?
2) cat & sed를 사용하여 각 변수를 값으로 대체하십시오.
주어진 template.txt :
The number is ${i}
The word is ${word}
명령:
cat template.txt | sed -e "s/\${i}/1/" | sed -e "s/\${word}/dog/"
많은 다른 기호를 벗어날 필요가 있고 나에게 많은 변수가 있기 때문에 선이 길어질 것 같습니다.
우아하고 안전한 다른 솔루션을 생각할 수 있습니까?
답변
이것을 사용할 수 있습니다 :
perl -p -i -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : $&/eg' < template.txt
모든 ${...}
문자열을 해당 환경 변수로 바꿉니다 (이 스크립트를 실행하기 전에 반드시 내보내는 것을 잊지 마십시오).
순수 bash의 경우 변수가 $ {…} 문자열을 포함하지 않는다고 가정하면 다음과 같이 작동합니다.
#!/bin/bash
while read -r line ; do
while [[ "$line" =~ (\$\{[a-zA-Z_][a-zA-Z_0-9]*\}) ]] ; do
LHS=${BASH_REMATCH[1]}
RHS="$(eval echo "\"$LHS\"")"
line=${line//$LHS/$RHS}
done
echo "$line"
done
. RHS가 자체를 참조하는 일부 변수를 참조하는 경우 중단되지 않는 솔루션 :
#!/bin/bash
line="$(cat; echo -n a)"
end_offset=${#line}
while [[ "${line:0:$end_offset}" =~ (.*)(\$\{([a-zA-Z_][a-zA-Z_0-9]*)\})(.*) ]] ; do
PRE="${BASH_REMATCH[1]}"
POST="${BASH_REMATCH[4]}${line:$end_offset:${#line}}"
VARNAME="${BASH_REMATCH[3]}"
eval 'VARVAL="$'$VARNAME'"'
line="$PRE$VARVAL$POST"
end_offset=${#PRE}
done
echo -n "${line:0:-1}"
경고 : bash에서 NUL로 입력을 올바르게 처리하거나 후행 줄 바꿈 양을 보존하는 방법을 모르겠습니다. 쉘은 바이너리 입력을 “사랑”하기 때문에 마지막 변형이 그대로 제공됩니다.
read
백 슬래시를 해석합니다.read -r
백 슬래시를 해석하지 않지만 줄 바꿈으로 끝나지 않으면 마지막 줄을 삭제합니다."$(…)"
본 있기 때문에 I 종료되도록 다수의 후미로 바꿈 벗길…
으로; echo -n a
사용echo -n "${line:0:-1}"
이 지난 (캐릭터 상품이다 :a
(더 포함한다)에 입력 없었다만큼 후미로 바꿈) 및 보존한다.
답변
시험 envsubst
FOO=foo
BAR=bar
export FOO BAR
envsubst <<EOF
FOO is $FOO
BAR is $BAR
EOF
답변
envsubst는 나에게 새로운 것이 었습니다. 환상적인.
레코드를 위해 heredoc을 사용하는 것이 conf 파일을 템플릿으로 만드는 좋은 방법입니다.
STATUS_URI="/hows-it-goin"; MONITOR_IP="10.10.2.15";
cat >/etc/apache2/conf.d/mod_status.conf <<EOF
<Location ${STATUS_URI}>
SetHandler server-status
Order deny,allow
Deny from all
Allow from ${MONITOR_IP}
</Location>
EOF
답변
sed 사용에 동의합니다. 검색 / 대체에 가장 적합한 도구입니다. 내 접근 방식은 다음과 같습니다.
$ cat template.txt
the number is ${i}
the dog's name is ${name}
$ cat replace.sed
s/${i}/5/
s/${name}/Fido/
$ sed -f replace.sed template.txt > out.txt
$ cat out.txt
the number is 5
the dog's name is Fido
답변
나는 평가가 정말 잘 작동한다고 생각합니다. 줄 바꿈, 공백 및 모든 종류의 bash 항목이있는 템플릿을 처리합니다. 물론 템플릿 자체를 완전히 제어 할 수있는 경우 :
$ cat template.txt
variable1 = ${variable1}
variable2 = $variable2
my-ip = \"$(curl -s ifconfig.me)\"
$ echo $variable1
AAA
$ echo $variable2
BBB
$ eval "echo \"$(<template.txt)\"" 2> /dev/null
variable1 = AAA
variable2 = BBB
my-ip = "11.22.33.44"
물론 eval은 임의의 코드를 실행할 수 있으므로이 방법은주의해서 사용해야합니다. 이것을 루트로 실행하는 것은 거의 문제가 아닙니다. 템플릿의 따옴표는 이스케이프 처리해야합니다. 그렇지 않으면으로 표시됩니다 eval
.
당신이 원하는 경우도 여기에 문서를 사용할 수 있습니다 cat
에echo
$ eval "cat <<< \"$(<template.txt)\"" 2> /dev/null
@plockc는 bash quote escaping 문제를 피하는 솔루션을 제안했습니다.
$ eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null
편집 : sudo를 사용하여 루트로 이것을 실행하는 것에 대한 부분을 제거했습니다 …
편집 : 따옴표를 이스케이프 처리하는 방법에 대한 의견을 추가하고 믹스에 plockc의 솔루션을 추가했습니다!
답변
mogsie와 같은 bash 솔루션이 있지만 herestring 대신 heredoc을 사용하면 큰 따옴표를 피할 수 있습니다.
eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null
답변
2017 년 1 월 6 일 편집
구성 파일에 큰 따옴표를 유지해야했기 때문에 sed help로 큰 따옴표를 이스케이프 처리하면 다음과 같습니다.
render_template() {
eval "echo \"$(sed 's/\"/\\\\"/g' $1)\""
}
나는 줄 바꿈 줄을 계속 생각할 수 없지만 그 사이의 빈 줄은 유지됩니다.
오래된 주제이지만 IMO에서 더 우아한 해결책을 찾았습니다 .http : //pempek.net/articles/2013/07/08/bash-sh-as-template-engine/
#!/bin/sh
# render a template configuration file
# expand variables + preserve formatting
render_template() {
eval "echo \"$(cat $1)\""
}
user="Gregory"
render_template /path/to/template.txt > path/to/configuration_file
Grégory Pakosz에 대한 모든 크레딧 .