sh는 상위 셸에서 bash 코드를 평가하고 이를 분리합니다.

sh는 상위 셸에서 bash 코드를 평가하고 이를 분리합니다.

이 코드가 있습니다세게 때리다스크립트:

r2g(){

   echo "executable is: $0"  # "/bin/bash"

  (
      set -e;
      r2g_internal "$@" \
       2> >( while read line; do echo "r2g error: $line"; done ) \
       1> >( while read line; do echo "r2g: $line"; done )
  )

    exit_code="$?"
    if [[ "$exit_code" != "0" ]]; then
        echo "something experienced an error, to see log, run: r2g_view_log";
        return 1;
    fi
}

r2g_internalsh를 실행한 후 분명히 bash 환경에 리소스를 제공하려고 시도하는 일부 프로세스에 의해 시작되고 sh에서 이상한 구문 오류가 발생합니다 .

r2g error: sh: r2g: line 2: syntax error near unexpected token `>'
r2g error: sh: r2g: line 2: ` r2g_internal "$@" 2> >( while read line; do echo "r2g error: $line"; done ) > >( while read line; do echo "r2g: $line"; done ) );'
r2g error: sh: error importing function definition for `r2g'

문제를 설명하기 위해 비디오를 만들었습니다. https://www.uselooom.com/share/82f23ebfe6754412a20be057957e45f4

후속 동영상: https://www.uselooom.com/share/0465c2857cc244879b52b7bdb516243e

을 실행할 때 npm install일부 프로세스는 .. sh에 의해 시작되어야 합니다 . npm가끔 git 명령을 실행하면 git프로세스 sh도 시작되는 것처럼 보이는데, 이 경우 터미널에 동일한 유형의 구문 오류가 표시됩니다.

bash를 통해 시작된 sh 프로세스가 상위 쉘/환경에서 bash 코드를 가져오려고 시도하는 이유를 이해할 수 없습니다.

이 비디오를 통해 문제가 더 명확해지기를 바랍니다.

에 전화하면 unset -f r2g문제가 즉시 해결됩니다. 그래서 내 r2g 함수가 호출되는 것 같지만 /bin/sh방법과 이유를 모르겠습니다.

다음은 r2g 및 r2g_internal의 소스 코드입니다. https://gist.github.com/ORESoftware/0fa7e3d6b75a65b17b6b126a7bec3397

답변1

이렇게 해도 문제가 해결되지 않을 수 있습니다. 잠시 시간을 내어 메모를 작성해 보세요. 댓글이 너무 깁니다.

  • 이거 할 필요 없으면 하지 마세요구조귀하의 코드를 한 줄로 인용하겠습니다.

    r2g_internal "$@"  2> >( while read line; do echo "r2g error: $line"; done ) 1> >( while read line; do echo "r2g: $line"; done )
    

    다른 사람들에게는, 심지어 당신조차도 읽기 어려울 것이라고 생각합니다.

  • 처음부터 시작하겠습니다.

    나는 보지 않았다셰르본좋다:

    #!/bin/bash
    

    또는

    #!/bin/sh
    

    등.

  • Bash가 필요하지 않지만 이 쉘 스크립트가 Bash를 요구하는 것 같으면 다음을 사용하십시오.POSIX sh이식성을 목적으로 합니다.

  • 한 번만 사용 되므로 exit_code피할 수 있습니다.

  • 항상 숫자를 인용할 필요는 없습니다. 이 경우에는 "$?".

  • Bash 관련 명령을 피하고 [[ .. ]]고전적인 테스트 명령을 사용하십시오. 이 경우:

    if [ $? -ne 0 ]
    
  • 줄 끝에 세미콜론을 추가할 필요가 없으며 다음과 같은 구조를 사용할 수 있습니다.

    if [ $? -ne 0 ]
    then
        echo "something experienced an error, to see log, run: r2g_view_log"
        return 1
    fi
    
  • -r스위치를 사용하여 read이 주제에 대해 자세히 알아보세요 .여기.

  • 저도 약간의 조정을 했는데요, 확인해 보시기 바랍니다.

  • 이것이 의도적인 것인지는 확실하지 않지만, return 1내가 보기에, 당신이 그것을 사용한 곳에서는 그렇지 않은 것 같습니다 exit 1.

  • 이것셰르본set -e다음이 포함될 수 있습니다 .

    #!/bin/bash -e
    

위 내용을 바탕으로 다시 작성했습니다.

#!/bin/bash -e

r2g()
{

    echo "executable name is: $0"

    r2g_internal "$@" 2> >( while read -r line; do echo "r2g error: $line"; done ) >( while read -r line; do echo "r2g: $line"; done )

    if [ $? -ne 0 ]
    then
        echo "something experienced an error, to see log, run: r2g_view_log"
        exit 1
    fi

}

답변2

공격하려는 의도는 없지만 오류 메시지를 읽고 이해해 보셨나요?

토큰 근처에서 예기치 않은 구문 오류가 발생했습니다 `>'

이는 코드에 명백한 오류가 포함되어 있음을 명시적으로 알려줍니다 2> >(. '>'는 표준 출력을 파일에 직접 기록합니다. r2g_internal의 출력을 표준 입력에서 읽는 스크립트로 보내려고 합니다. '를 사용해야 합니다.|'>' 대신 '.

또 하나의 버그 - stdout과 stderr에 별도의 파일을 지시할 수 있지만 쉽게 별도의 스크립트에 지시할 수는 없습니다. 먼저 파일에 기록한 다음 개별적으로 처리해야 합니다.

r2g_internal "$@" 1> stdout.txt 2> stderr.txt
cat stderr.txt | ( while read line; do echo "r2g error: $line"; done )
cat stdout.txt | ( while read line; do echo "r2g: $line"; done )

관련 정보