Bash에서 printf 명령의 내부 작동 방식을 설명해 주실 수 있나요?

Bash에서 printf 명령의 내부 작동 방식을 설명해 주실 수 있나요?

나는이 질문을 우연히 발견했습니다.특정 변수만 envsubst로 대체그리고 그 중 한 곳에서논평이 셸 예제는 다음과 같습니다.

envsubst "$(printf '${%s} ' ${!PREFIX*})" < infile

전체 배경에 대한 원래 질문을 참조하세요. 그러나 본질적으로 envsubst는 문자열 "PREFIX"로 시작하는 환경 변수만 바꾸도록 지시합니다.

그런데 이것이 어떻게 작동하나요? 누군가 관련된 다양한 "단계"를 설명할 수 있습니까? infile을 먼저 읽으시나요? 파일의 입력을 사용할 수 있도록 grep/find와 같은 작업을 수행하는 부분은 무엇입니까? 매개변수 "${!PREFIX*}"는 일종의 정규식인가요? 여기에 서브쉘 마법이 일어나고 있나요?

더 잘 이해하기 위해 다음 내용으로 나만의 infile을 만들었습니다.

1: ${VAR1}
2: ${VAR2}
3: ${VAR3}
4: ${PREFIX_1}
5: ${PREFIX_2}
6: ${PREFIX_3} ?
7: ${PREFIX_4} + ${PREFIX_5}
8: ${VAR4}
9: bla bla bla

그런 다음 envsubst를 echo로 바꾸었고 결과는 다음과 같습니다.

echo "$(printf '${%s} ' ${!PREFIX*})" < infile

이 결과는 다음과 같습니다.

${PREFIX_1}

따라서 작동하지만 첫 번째 게임에만 해당됩니다. 내가 뭘 잘못했나요? 출력에는 모든 "PREFIX_" 변수 1~5가 포함될 것으로 예상됩니다. envsubst를 echo로 교체했을 때 내가 엉망이 된 것일까요? 그렇다면 envsubst로 전송되는 내용을 어떻게 확인할 수 있습니까?

답변1

${!prefix_*}로 시작하는 모든 쉘 변수의 이름으로 확장되는 Bash 기능입니다 prefix_. 그런 다음 명령의 대체 내용을 printf중괄호 안에 인쇄합니다(필요한 만큼 형식 문자열을 반복합니다).

$ prefix_foo=1 prefix_bar=2
$ printf '${%s}\n' ${!prefix_*}
${prefix_bar}
${prefix_foo}

명령 대체 때문에 envsubst명령줄에서 삭제됩니다. 확장 및 명령 대체 결과에는 단어 분리가 포함되지만 변수 이름에는 공백이나 와일드카드가 포함될 수 없으므로 이는 기본값과 관련이 없습니다.${!prefix_*}IFS

echo "$(printf '${%s} ' ${!PREFIX*})" < infile

여기서는 표준 입력에서 아무것도 읽히지 않으므로 내용은 infile중요하지 않습니다 . echo로 시작하는 변수 이름만 인쇄됩니다 PREFIX.

관련 정보