이 질문은 렌더 템플릿 사용에 관한 것입니다 sed
.
템플릿 파일이 있습니다 nginx_app
.
server {
root ${drt}/${domain}/;
server_name ${domain} www.${domain};
}
이 파일을 다른 스크립트에서 사용합니다.
#!/bin/bash
domain="$1" && test -z ${domain} && return
sed "s/\${domain}/${1}/g" "nginx_app" > "/etc/nginx/sites-available/${domain}.conf"
물론 목적은 example.com.conf
이를 기반으로 렌더링 템플릿으로 사용하는 것입니다.nginx_app
위의 코드를 고려해보세요:
sed "s/\${domain}/${1}/g" "nginx_app" > "/etc/nginx/sites-available/${domain}.conf"
내가 이해한 바로는 이 코드는 다음을 수행합니다.
${domain}
${1}
()의 스크립트 인수를 기반으로 (아직 확장되지 않은) 문자열을 변경 합니다example.com
.메모리이지만nginx_app
파일 자체는 변경되지 않습니다.nginx_app
렌더링된 버전 을/etc/nginx/sites-available/${domain}.conf
.
여기에서 정확하다고 가정하면 코드를 보면 이러한 작업이 나에게 매우 직관적이지 않다고 말해야 합니다. 이 코드에 대한 설명이 정확합니까?
내 설명이 충분히 정확하지 않은 경우 정정해 주세요.
답변1
예, 본문의 두 번째 부분에 대한 귀하의 이해가 정확합니다.
sed
다른 많은 Unix 도구와 마찬가지로 다음과 같이 작동한다고 말할 수 있습니다.필터. 필터는 입력을 받아 수정하고 출력을 생성합니다. 많은 경우 필터링을 수행하는 유틸리티는 읽기 또는 쓰기 중인지조차 모를 수 있습니다.문서. 실제로 다른 필터 유틸리티에서 직접 읽거나 쓸 수 있습니다. 이는 유틸리티 자체에 투명하며 쉘에 의해 설정됩니다.
다음과 같은 불필요한 사용법 사실을 무시하십시오 cat
.
cat <file | sed 's/^\([^=]*\)=\(.*\)$/#\1=\2 # old/' | tr -s ' ' >newfile
위의 유틸리티 중 어느 것도 파일 읽기 또는 쓰기에 대해 알지 못합니다. cat
에서 읽다표준 입력 스트림(셸은 의 데이터를 포함하도록 배열합니다 file
.) 한 번에 한 줄씩 출력을 기록합니다.표준 출력 스트림(수정이 필요하지 않습니다).
sed
다음에서 읽기그것은표준 입력 스트림(셸이 연결된 출력 스트림 cat
)은 각 입력 줄을 일부 수정하고 그 결과를 표준 출력 스트림(연결된 tr
)에 씁니다.
tr
또한 표준 출력에만 기록하지만 쉘은 출력이 파일로 이동하는 방식으로 리디렉션을 설정합니다 newfile
.
프로세스의 각 단계에서 각 유틸리티는 파이프를 통해 필요한 최소한의 데이터(RAM에 할당된 버퍼)만 저장할 수 있습니다. 이는 newfile
파일의 데이터를 완전히 읽기 file
전에 결과가 기록되기 시작할 수 있음을 의미합니다(이 예에서는) .
구체적인 예:
sed "s/\${domain}/${1}/g" "nginx_app" > "/etc/nginx/sites-available/${domain}.conf"
무슨 일이에요:
쉘은 명령줄을 구문 분석하고 변수와 리디렉션을 찾습니다.
파일
/etc/nginx/sites-available/${domain}.conf
($domain
이 변수의 값으로 확장됨)이 있으면 잘리거나 지워지고, 없으면 빈 파일로 생성됩니다.유틸리티는
sed
피연산자(해당 값으로 확장되었지만 로 이스케이프되었기 때문에 아직 확장되지 않음) 및 를 사용하여 호출됩니다. 쉘은 또한 표준 출력을 리디렉션하려는 파일에 연결합니다.s/\${domain}/${1}/g
$1
${domain}
$
\
nginx_app
sed
피연산자가 두 개 있으므로
sed
두 번째 피연산자가 읽을 파일이라고 가정합니다. 첫 번째 피연산자에 편집 명령을 적용하면서 이를 열고 한 줄씩 읽습니다.모든 출력은 리디렉션되는 파일로 들어갑니다.
사람들이 언급한 이후 sed -i
:
-i
주어진 파일을 sed
변경 하게 하는 플래그sed
제자리에즉, 표준 출력에 쓰지 않지만 변경 결과는 입력에 사용된 동일한 파일에 반영됩니다.
내부적으로는 sed
글을 써서임시 파일나중에 원본 파일을 해당 파일로 대체합니다.
이 -i
플래그는 하나의 인수( sed
GNU 및 이 유틸리티의 일부 다른 구현의 경우 선택 사항, 다른 유틸리티의 경우 필수) 인수를 사용합니다.
sed -i .bak '...some sed script...' filename
이렇게 하면 지정된 문자열을 새 파일 이름 접미사로 사용하여 원본 파일이 백업됩니다.
나는 일반적으로 다음과 같은 이유로 사람들이 -i
with를 사용하지 못하도록 막으려고 합니다 .sed
- 비표준 확장입니다.POSIX 표준
sed
. - 다른 Unices에서는 다르게 동작합니다. 이슈 보기sed -i(제자리에서 편집)를 사용하여 이식성을 달성하는 방법은 무엇입니까?
sed
스크립트에 문제가 있을 경우 데이터가 손상될 수 있으므로 스크립트를 테스트하거나 개발할 때 사용하는 것은 위험합니다 .
대신에 나는 사람들에게 다음과 같은 일을 하라고 제안합니다.
sed '...some sed script...' file >file-new && mv file-new file
&& mv
sed
... 올바른 테스트를 거친 후에 만 부품을 추가하세요.
&& mv
"이전 명령이 오류 없이 성공적으로 종료된 경우 파일 이름을 바꾸십시오"를 의미합니다 .
답변2
이 -i
플래그가 없으면 모든 명령의 결과가 sed
표준 출력에 기록됩니다.
이 예에서는 표준 출력을 다른 파일( )로 리디렉션합니다 /etc/nginx/sites-available/${domain}.conf
.
답변3
sed
파일에 직접 쓰는 대신 출력을 파일로 리디렉션해야 하는 이유를 묻는 것 같습니다 . 그렇다면 몇 가지 이유가 있습니다.
- 실제로
-i
의 매개변수를 통해 이 작업을 수행 할 수 있습니다sed
. - 이는 다른 프로그램과 통신하는 프로그램을 설계하는 일반적인 UNIX 철학을 따르지 않기 때문에 기본 동작이 아닙니다(https://en.wikipedia.org/wiki/Unix_philosophy).
많은 UNIX 쉘 유틸리티의 기본 개념은 이들을 서로 연결하는 것입니다(foo | bar | baz
). 이를 통해 각 단계 사이에 데이터를 디스크에 버퍼링하지 않고도 데이터에 대한 복잡한 처리를 수행할 수 있습니다.