답변:
이것은 매우 가능합니다. 이것을 구현하는 매우 간단한 방법은 템플릿 파일이 실제로 스크립트이고 다음과 같은 쉘 변수를 사용하는 것입니다
#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
cat > /tmp/destfile <<-EOF
here is some config for version $version which should
also reference this path $path
EOF
version=$1
및 을 지정하여 명령 줄에서이 설정을 구성 path=$2
할 수 있으므로 다음과 같이 실행할 수 있습니다 bash script /foo/bar/baz 1.2.3
. 는 -
EOF가 라인을 무시하기 전에 공백이 발생하기 전에, 일반 사용 <<EOF
당신이 그 행동을하지 않으려면.
이 작업을 수행하는 또 다른 방법은 sed의 검색 및 교체 기능을 사용하는 것입니다
#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
sed -e "s/VERSION/$version/g" -e "s/PATH/$path/" /path/to/templatefile > /tmp/destfile
VERSION 및 PATH 문자열의 각 인스턴스를 대체합니다. 이러한 문자열이 템플릿 파일에있는 다른 이유가있는 경우 검색 및 교체를 VERSION 또는 % VERSION % 또는 실수로 트리거 할 가능성이 적은 것으로 만들 수 있습니다.
이외의 도구는 필요하지 않습니다 /bin/sh
. 양식의 템플릿 파일이 주어짐
Version: ${version}
Path: ${path}
또는 혼합 쉘 코드가 포함 된 경우에도
Version: ${version}
Path: ${path}
Cost: ${cost}\$
$(i=1; for w in one two three four; do echo Param${i}: ${w}; i=$(expr $i + 1); done)
셸 파싱 가능한 구성 파일
version="1.2.3-r42"
path="/some/place/under/the/rainbow/where/files/dance/in/happiness"
cost="42"
이것을 확장하는 것은 간단한 일입니다.
Version: 1.2.3-r42
Path: /some/place/under/the/rainbow/where/files/dance/in/happiness
Cost: 42$
Param1: one
Param2: two
Param3: three
Param4: four
실제로 쉘 변수의 구성 파일 config_file
경로와의 템플릿 파일 경로 template_file
는 다음과 같습니다.
. ${config_file}
template="$(cat ${template_file})"
eval "echo \"${template}\""
이것은 아마도 완전한 쉘 스크립트를 템플릿 파일 (@mtinberg의 솔루션)로 사용하는 것보다 더 좋습니다.
완전한 순진한 템플릿 확장 프로그램 :
#!/bin/sh
PROG=$(basename $0)
usage()
{
echo "${PROG} <template-file> [ <config-file> ]"
}
expand()
{
local template="$(cat $1)"
eval "echo \"${template}\""
}
case $# in
1) expand "$1";;
2) . "$2"; expand "$1";;
*) usage; exit 0;;
esac
확장을 표준 출력으로 출력합니다. 표준 출력을 파일로 리디렉션하거나 원하는 방식으로 원하는 출력 파일을 생성하기 위해 위의 방식으로 수정하십시오.
주의 사항 : 파일에 이스케이프되지 않은 큰 따옴표 ( "
)가 포함 된 경우 템플릿 파일 확장이 작동하지 않습니다 . 보안상의 이유로 템플릿 파일이 외부 엔터티에 의해 생성되는 경우 명백한 무결성 검사를 포함하거나 셸 이스케이프 변환을 수행하는 것이 좋습니다.
Linux CLI에서 간단하게 수행하는 가장 쉬운 방법은 envsubst
환경 변수 를 사용하는 것 입니다.
예제 템플릿 파일 apache.tmpl
:
<VirtualHost *:${PORT}>
ServerName ${SERVER_NAME}
ServerAlias ${SERVER_ALIAS}
DocumentRoot "${DOCUMENT_ROOT}"
</VirtualHost>
실행 envsubst
하고 결과를 새 파일로 출력하십시오 my_apache_site.conf
.
export PORT="443"
export SERVER_NAME="example.com"
export SERVER_ALIAS="www.example.com"
export DOCUMENT_ROOT="/var/www/html/"
envsubst < apache.tmpl > my_apache_site.conf
산출:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot "/var/www/html/"
</VirtualHost>
name
의 문자열 <%= name %>
이 name
의 값으로 대체됩니다 . name
템플릿 외부에서 정의하는 방법 은 분명히 두 시스템간에 다릅니다.
새 파일을 생성하는 쉘 코드가 아닌 가볍고 실제 템플릿을 원한다면 일반적인 선택은 sed
& awk
또는 perl
입니다. 하나의 링크는 다음과 같습니다. http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/
나는 perl, tcl, python, ruby 또는 그 클래스의 다른 언어와 같은 실제 언어를 사용합니다. 스크립팅을 위해 구축 된 것입니다. 그들은 모두 훌륭하고 간단한 템플릿 도구와 Google에 많은 예제를 가지고 있습니다.
나는 그것을 위해 shtpl 을 사용 합니다. (비공개 프로젝트, 즉 널리 사용되지는 않습니다. 그러나 어쨌든 테스트하고 싶을 수도 있습니다)
예를 들어 csv 파일에서 / etc / network / interfaces를 생성하려면 다음과 같이하십시오.
CSV 파일 내용 (여기서는 test.csv) :
eth0;10.1.0.10;255.255.0.0;10.1.0.1
eth1;192.168.0.10; 255.255.255.0;192.168.0.1
템플릿 (여기에서 interfaces.tpl) :
#% IFS=';'
#% while read "Val1" "Val2" "Val3" "Val4"; do
auto $Val1
iface $Val1 inet static
address $Val2
netmask $Val3
gateway $Val4
#% done < "$CSVFILE"
명령:
$ CSVFILE=test.csv sh -c "$( shtpl interfaces.tpl )"
결과:
auto eth0
iface eth0 inet static
address 10.1.0.10
netmask 255.255.0.0
gateway 10.1.0.1
auto eth1
iface eth1 inet static
address 192.168.0.10
netmask 255.255.255.0
gateway 192.168.0.1
즐겨!
최근에 jinja와 같은 템플릿 구문을 사용하여 bash 스크립트를 작성했습니다. 쿠키 라고 합니다. 데모는 다음과 같습니다.
아마이 파티에 늦었을 것입니다. 그러나 나는 똑같은 문제에 대해 우연히 만났고 몇 줄의 코드로 나만의 BASH 템플릿 엔진을 만들기로 결정했습니다.
이것을 가지고 있다고 가정 해 봅시다 file.template
.
# My template
## Author
- @NAME@ <@EMAIL@>
그리고이 rules
파일 :
NAME=LEOPOLDO WINSTON
EMAIL=leothewinston\@leoserver.com
이 명령을 실행합니다 :
templater rules < file.template
당신은 이것을 얻는다 :
# My template
## Author
- LEOPOLDO WINSTON <leothewinston@leoserver.com>
다음을 통해 설치할 수 있습니다.
bpkg install vicentebolea/bash-templater
이것은 프로젝트 사이트입니다
heredoc + 제어 문자를 사용하여 @FooF의 훌륭한 답변 (줄 바꿈이 주석에서 형식화되지 않음)을 확장하려면 임의의 문자 와 파일 이름을 허용 할 수 있습니다 .
template() {
# if [ "$#" -eq 0 ] ; then return; fi # or just error
eval "cat <<$(printf '\x04\x04\x04');
$(cat $1)
"
}
이것은 널이 아닌 문자를 허용하며 3 ^D
바이트가 자신의 행에서 발견 될 때만 잘립니다 (실제로는 절대). zsh는 null 종결자를 지원하기 때문에 printf '\x00\x00\x00'
작동합니다. template
위험한 파일 이름에서도 작동합니다.
for num in `seq 10`; do
template 'foo "$ .html' # works
done
쉘 템플리트는 임의의 명령을 "확장"할 수 있습니다 (예 :) $(launch_nukes.sh --target $(curl -sL https://freegeoip.app/csv/ | cut -d, -f 9,10))
. 큰 힘으로…
편집 : 파일이 실제로 핵 공격을 시작하지 않으려면 sudo -u nobody sh
미리 (또는 다른 안전한 사용자) 미리하십시오.