systemd에서 대시의 최대 가변 길이

systemd에서 대시의 최대 가변 길이

KEY=VALUE단일 변수를 연관 배열( 한 줄에 하나씩) 로 사용하는 쉘 스크립트가 있습니다 .

스크립트가 실행되는 동안 변수는 항목을 추가, 제거 또는 수정하기 위해 조작됩니다.

추가의:

VARIABLE="$(printf "%s\n%s" "$VARIABLE" "KEY=VALUE")"

조정:

VARIABLE="$(printf "%s\n" "$VARIABLE" | sed -E "s,^(KEY=).*$,\1VALUE,")"

제거하다:

VARIABLE="$(printf "%s\n" "$VARIABLE" | grep -E -v "^KEY=.*$")"

터미널에서 실행되는 경우(또는 이전 시스템의 서비스로)체계init 스크립트를 통해) 잘 실행되지만 서비스로 실행될 때는체계잠시 후 스크립트는 로그에 오류 메시지를 표시하기 시작합니다.

sh: printf: I/O error

많은 시행착오 끝에 스크립트의 어떤 명령이 이러한 오류를 생성했는지 알 수 없었지만 변수 길이가 8000바이트에 도달하면(8192로 추측되지만 정확히 알 수는 없음) 정확히 내가 전체 줄을 추가한 이후로).

변수 길이가 8192바이트에 도달할 때마다 배열에서 가장 오래된 항목을 잘라내는 루틴을 구현했기 때문에 변수 길이가 문제라고 확신합니다. 이제 스크립트는 systemd오류 없이 오랫동안 실행됩니다. 일부 정보가 손실되므로 이상적이지 않습니다.

쉘 스크립트의 최대 변수 길이에 대한 정보를 온라인에서 검색했지만 유용한 정보를 찾지 못했습니다.

  • dash매뉴얼 페이지에는 최대 변수 길이가 언급되어 있지 않습니다.

  • GNU sed 문서설명하다:

휴대용으로 쓰고 싶으신 분들은sed스크립트의 경우 일부 구현에서는 줄 길이(패턴 및 예약된 공간)를 4000바이트 이하로 제한하는 것으로 알려져 있습니다. 이것POSIX표준 요구 사항은 다음을 준수합니다.sed구현은 최소 8192바이트의 줄 길이를 지원해야 합니다(SHOULD).GNU sed가능한 한 줄 길이에 대한 기본 제한은 없습니다.malloc()더 많은 (가상) 메모리를 사용하면 필요에 따라 라인을 제공하거나 구축할 수 있습니다.

...그러나 이는 다음에 적용됩니다.철사전체 텍스트 길이가 아닌 길이(한 줄에 80자 이하)

어쨌든 오류는 스크립트가 실행 중일 때만 나타나기 때문에 systemd유닛 파일에서 LimitMSGQUEUE및/또는 증가를 시도했지만 LimitSTACK소용이 없었습니다. (메시지 큐나 프로세스 스택의 개념을 완전히 이해하지 못하기 때문에 이것은 맹목적인 추측입니다. 그러나 표시된 숫자는 systemctl show8KB 정도인 것 같습니다. 메모리( LimitRSS, LimitAS, ) 에 관한 다른 모든 제한은 LimitMEMLOCK충분히 높은 것 같아서(8192바이트를 훨씬 넘음) 다음에 무엇을 해야 할지 모르겠습니다.

systemd변수 길이가 8KB를 초과할 때 이 스크립트가 제대로 실행되도록 하려면 어떻게 해야 합니까?

답변1

답보다는 진단에 가깝다…

내 시스템에서 다음을 실행하세요.dash v0.5.8-2.10, 가변 길이는 적어도 상당히 클 수 있습니다.2^30성격. ${x}문자 길이가 약을 초과할 때까지 변수 길이를 두 배로 늘리는 데모입니다 ${#x}.25%사용 가능한 메모리(구성:애드 혹 furp기능):

첫 번째 시작 dash:

dash

그런 다음 dash(에서) 다음 코드를 실행합니다.

furp() { free | { read z; read a b c d; echo $((100*$c/$b)) ; } }
x=1
while [ `furp` -lt 25 ] ; do 
    x="${x}${x}"; echo ${#x}
done | tail -1

출력(내 시스템에서는 사용 가능한 메모리에 따라 달라질 수 있음):

1073741824

위와 같은 코드를 스크립트에 넣은 후 systemd동일한 환경에서 실행하고 출력을 확인해 보세요.

답변2

(표현력이 부족해서)

"sh: printf: I/O error"는 스크립트가 systemd sh가 아닌 사용하여 실행되었음을 의미합니다 dash. 아마도 이것이 diff가 작동하는 곳일까요?

관련 정보