dash: 내 스크립트에 백틱이 포함되어 있지 않은데 "구문 오류: 백틱 대체의 EOF" 오류가 발생하는 이유는 무엇입니까?

dash: 내 스크립트에 백틱이 포함되어 있지 않은데 "구문 오류: 백틱 대체의 EOF" 오류가 발생하는 이유는 무엇입니까?
#!/bin/sh --

for set_trap_sig in HUP INT QUIT ALRM TERM; do
    trap -- '
        trap -- - '"${set_trap_sig:?}"' EXIT || exit "$?"
        kill -s '"${set_trap_sig:?}"' -- "$$" || exit "$?"' "$set_trap_sig"
done

sleep 15 || exit "$?"

SIGINT를 스크립트에 보내면 이런 일이 발생합니다.

user@hostname:/tmp$ ./script.sh
^C./script.sh: 3: ./script.sh: Syntax error: EOF in backquote substitution

이 질문은 대시에만 해당되는 것 같습니다. ash, bash 및 ksh93에서는 이 오류가 발생하지 않습니다. 내 스크립트에 백틱 문자도 포함되어 있지 않기 때문에 이것은 특히 이상합니다.

5행 끝에서 큰따옴표를 제거하면 $?오류가 사라집니다.

내가 멍청한 짓을 하고 있는 걸까요, 아니면 대시가 오작동하는 걸까요? 내 스크립트의 오류 검사 수준에 대해 언급하지 마십시오.

이제 우리는 이것이 최신 버전의 Ubuntu 및 Debian에도 영향을 미치는 매우 심각한 버그라는 것을 확인했습니다. 누구든지 해결책을 알고 있습니까?

답변1

다음은 단순화된 테스트 사례입니다.

trap '
        trap    - HUP EXIT || exit "$?"
        kill -s HUP    "$$" || exit "$?" ' HUP INT
kill -HUP $$
$ dash dash-bug
dash-bug: 3: /home2/ahq/dash-bug: Syntax error: EOF in backquote substitution

참조된 코드의 길이나 내용을 수정하면 버그가 "수정"되거나 무작위 바이트가 나타나는 등 다양하고 흥미로운 손상이 발생할 수 있습니다.

이는 대시 0.5.9 이후 수정되었지만 Debian 9.8 stable(stretch), Ubuntu 18.04(bionic) 및 Ubuntu 18.10(cosmic)의 대시 0.5.8에는 여전히 존재하는 use-after-free 버그로 인해 발생합니다.

이것은범죄고쳤다:

commit 6c3f73bc536082fec38bd36e6c8a121033c68835
Author: Herbert Xu <[email protected]>
Date:   Thu Oct 2 08:26:06 2014 +0800

    [EVAL] Fix use-after-free in dotrap/evalstring

    The function dotrap calls evalstring using the stored trap string.
    If evalstring then unsets that exact trap string then we will end
    up using freed memory.

    This patch fixes it by making evalstring always duplicate the string
    before using it.

    Signed-off-by: Herbert Xu <[email protected]>

해결 방법은 트랩 핸들러를 함수에 넣는 것입니다. 그러면 트랩이 설정 해제된 후 명령이 실행되지 않고 해제된 후 작업 문자열을 사용해 보십시오.

sighandler(){
    trap - "$sig" EXIT || exit "$?"
    kill -s "$sig" "$$" || exit "$?"
}
for sig in HUP INT QUIT ALRM TERM; do
    trap "sig=$sig; sighandler" "$sig"
done

kill -s HUP "$$"

관련 정보