매개변수가 너무 긴 문제를 해결하는 방법

매개변수가 너무 긴 문제를 해결하는 방법

저는 쉘 스크립팅을 처음 접했습니다. 동적 HTML 콘텐츠를 생성하고 해당 콘텐츠를 변수에 할당하고 이 변수 ​​값을 사용하여 셸(Linux) 내부의 템플릿을 바꿔야 하는 기존 셸 스크립트를 수정하고 있습니다.

아래 코드 조각을 사용하고 있는데 html 콘텐츠가 적을 때는 제대로 작동하지만 콘텐츠가 크면 똑같이 실패합니다. 이 문제를 해결하는 방법.

encStr="$(cat ./dynamiccontent.html | base64)"
echo $encStr
awk -v var="$encStr" '{gsub("REPLACECONTENT", var, $0); print}' /path/tomytemplate > output.tmp

답변1

@mosvy는 이미 훌륭한 답변을 주셨습니다.

이야기의 간략한 교훈은 다음과 같습니다. 검증되지 않은 길이의 데이터를 저장하기 위해 쉘 변수를 사용하는 것은 좋은 생각이 아닙니다. 일반적으로 쉘 변수나 쉘을 사용하는 것은 프로그래밍 언어를 혼란스럽게 하기 때문에 전혀 좋은 생각이 아닙니다. 그러나 반드시 쉘 변수에 무언가를 저장해야 한다면 다음과 같은 미친 짓을 단계별로 시도해 볼 수도 있습니다.

프로세스 교체를 통해 모든 내용이 포함된 임시 파일을 만듭니다. 사실 쉘 내장 기능에는 일반적인 하위 프로세스 매개변수 제한이 적용되지 않습니다.

awk -v patternFile=<( printf "$encStr" )

AWK를 사용하는 지루한 방법(결국 이는 일반적으로 라인 지향 Unix 도구임), 전체 임시 파일을 AWK 변수 "contents"로 읽고, 먼저 이를 라인으로 분할한 다음 문자열 연결을 사용하여 재구성하고, 임의의 항목을 추가하는 지루한 방법입니다. 개행은 분할로 제거됩니다.

awk -v substitutionFile=<( printf "$encStr" ) 'BEGIN {while ((getline line <substitutionFile) > 0) { contents = contents line "\n"}}'

그런 다음 템플릿 파일에서 대체할 태그를 결정하는 데 이미 사용했던 일반 줄 중심 방식으로 대체를 수행합니다.

awk -v substitutionFile=<( printf "$encStr" ) 'BEGIN {while ((getline line <substitutionFile) > 0) { substitutionString = substitutionString line "\n"}} {gsub("REPLACECONTENT", substitutionString, $0); print}' /path/tomytemplate > output.tmp

이제 위의 솔루션은 보기 흉합니다... 하지만 *nix 쉘 표준으로는 충분히 보기 흉하지 않습니다! 이미 *nix 쉘을 사용하고 있다면 heredoc을 사용하면 어떨까요? 이렇게 하면 printf 명령이 함수로 재정의될 위험이 줄어들지만(내 시스템, 프로덕션 코드에서는 실패합니다 :D), heredoc 구분 기호가 포함된 파일의 위험이 높아집니다.

awk -v substitutionFile=<( cat <<HOPEFULLY_UNIQUE_HEREDOC_DELIMITER
$encStr
HOPEFULLY_UNIQUE_HEREDOC_DELIMITER
) 'BEGIN {while ((getline line <substitutionFile) > 0) { substitutionString = substitutionString line "\n"}} {gsub("REPLACECONTENT", substitutionString, $0); print}' /path/tomytemplate > output.tmp

구분된 문서의 변수 대체는 따옴표로 계산되므로 quote 를 사용하면 안 됩니다 $encStr. 그렇지 않으면 대체 문자열에도 따옴표가 포함됩니다! 이는 쉘 대체에 대한 규칙 1749203입니다. 다른 경우의 주요 규칙은 간단합니다. 변수 및 명령 대체에 큰따옴표를 사용하지 않으면 죽습니다.

이 경우 cat내장 파일이 아니라는 것은 중요하지 않습니다. 왜냐하면 표준 입력을 heredoc에 의해 생성된 임시 파일로 리디렉션하기 때문입니다. 이 파일 자체에는 매개변수 전달이 포함되지 않기 때문에 길이 제한이 없습니다.

관련 정보