typeset -f는 실제 정의를 인쇄하지 않습니다. 감지/수정할 수 있나요?

typeset -f는 실제 정의를 인쇄하지 않습니다. 감지/수정할 수 있나요?

이 버그가 Bash에 존재한다는 것을 발견하는 데 어제 대부분의 시간이 걸렸습니다.

outer () 
{ 
    function inner () 
    { 
        cat <<_EOS
foo
_EOS
    }
    inner
}

다음 과 같이 표시됩니다 typeset -f outer.

outer () 
{ 
    function inner () 
    { 
        cat <<_EOS
    }
foo
_EOS
    inner
}

이것은 분명히 다릅니다. CygWin(bash 4.4.12)에서는 출력 오류가 다른 방식으로 발생합니다.

outer ()
{
    function inner ()
    {
        cat
    } <<_EOS
foo
_EOS

    inner
}

이 버그는 최신 버전의 Bash에서 수정되었습니다.

나는 이것을 사용하여 env_parallel... env_parallel출력이 typeset -f올바른지 여부에 따라 다릅니다.

env_parallel이것은 코너 케이스 버그이므로 결과에 영향을 줄 수 있는 실제 위험이 없는 한 경고를 발행 하고 싶지 않습니다 . 반면에 실제 위험이 있는 경우 사용자가 어제처럼 좌절감을 느끼는 것을 정말로 원하지 않기 때문에 경고를 받고 싶습니다.

출력에 버그가 있는 경우 이를 안정적으로 감지할 수 있습니까 typeset -f? bash 파서를 작성하지 않고도 수정할 수 있나요?

답변1

일부 코드가 구문적으로 유효한지 확인할 수 있습니다.

if bash -O extglob -n < some-code 2> /dev/null; then
  echo that seems valid
fi

그러나 구문은 extglob별칭, 로케일 설정(LC_CTYPE 범주) 및 bash의 옵션에 의해 영향을 받을 수 있습니다.

예를 들어, 코드 조각은 on이 사용될 때 유효 extglob하지만 그렇지 않을 때는 유효하지 않을 수 있으며(예: ) 일반적으로 그 반대일 수 있으므로 on을 사용하여 구문을 확인하는 echo @(x)것이 좋습니다 .extglob

코드 조각은 변수 이름의 유효한 문자와 마찬가지로 한 로케일에서는 유효하지만 다른 로케일에서는 유효하지 않을 수 있습니다( $'\xe9=(x)'해당 로케일에서는 유효 fr_FR.iso88591하지만 UTF-8 로케일이나 C 로케일에서는 유효하지 않음). (토큰 구분 기호로 사용할 수도 있습니다!) )은 로케일에 따라 다릅니다(따라서 typeset -f버전이 다르거나 동일한 시스템의 동일한 로케일에서 실행되지 않는 다른 bash 호출의 출력을 제공하는 것도 종종 위험합니다).

alias forever='while true; do'
forever echo test; done

는 valid 로 보고되지만 명령이 실행 되면 두 번째 줄이 유효해지기 때문 bash -n이 아닙니다 . 그러나 이는 출력 구문을 확인할 때 문제가 되지 않습니다 .bash -O expand_aliasesaliastypeset -f

여기서 이를 사용하여 이 오류나 다른 오류로 인해 발생한 구문 오류를 감지할 수 있지만 위의 고려 사항으로 인해 완벽하지는 않을 뿐만 아니라 오류가 실수로 유효한 코드를 생성할 수도 있기 때문입니다.

관련 정보