UNIX 쉘이 왜 이런가요? 어떻게 해결할 수 있나요?

UNIX 쉘이 왜 이런가요? 어떻게 해결할 수 있나요?

BASH 및 기타 UNIX 셸에 대해 제가 알아차린 한 가지는 기본적으로 그리고 일반적인 방식으로 사용될 때 거의 모든 것에 대한 하위 셸을 생성한다는 것입니다.

예를 들어

foo=$(grep "someword" /path/to/somefile | awk '{print $3}')

일부 텍스트를 변수에 로드하기 위해 두 개의 새로운 bash 세션이 생성됩니다.

a) 쉘이 왜 이런 일을 하는가? 명령줄 프로그램이 파일 설명자에서 작동하는 경우 설명자를 제공하기 위해 새로운 비대화형 셸 세션을 생성할 필요가 없습니다. 그렇죠?

b) 명령 출력을 변수에 로드할 때 이 문제를 해결하는 가장 좋은 방법은 무엇입니까? Bash에서 다음을 사용할 수 있다는 것을 알고 있습니다.

read -r -d '' < <(...)

서브쉘을 사용하지 않고 명령에서 변수를 설정하는 것이 가능하지만 이는 매우 번거롭고 더 나은(그리고 더 이식성이 뛰어난) 방법을 찾고 있습니다. (다시 말하지만, 파이프와 명령 대체에 대한 일반적인 대안을 아는 사람이 있다면 정말 좋을 것입니다.아니요서브쉘이 관련됩니다. )

참고: "Perl/Python/Ruby 사용자"가 "올바른" 솔루션일 수 있다는 것을 알고 있지만 이러한 솔루션에는 파일 작업, 외부 명령 호출 등에 대해 많은 상용구 코드가 필요한 경향이 있습니다.

편집: 아래 답변에 감사드립니다. 하지만 프로세스 교체가 새 쉘을 포크해야 하는 이유는 아직 설명되지 않습니다.내장 명령의 경우에도:

$ builtin echo $(builtin echo $(builtin echo $BASH_SUBSHELL))
2

답변1

grep또는 같은 명령을 실행하려면 awk쉘이 분기되어야 합니다. 즉, 하위 쉘을 얻게 됩니다. 유일한 예외는 명령이 내장 명령인 경우 또는 명령이 마지막 명령인 경우입니다. 그러나 후자의 경우는 동작을 변경할 수 있는 특정 조건(예: 기존 트랩)에서 수행할 수 없는 일부 쉘에 의해 수행되는 최적화일 뿐입니다 exec. 따라서 두 개의 하위 쉘

foo=$(grep "someword" /path/to/somefile | awk '{print $3}')

서브셸을 방지하려면 여러 가지 해결 방법이 있으며 상황에 따라 찾아야 합니다.

답변2

a)에 중점을 둡니다.

주문 실행

foo=$(echo bar)

명령이 명령 대체를 사용하므로 서브셸을 시작합니다. 이는 서브셸이 사용되는 환경으로 작동함을 의미합니다.

주문하다명시적으로 서브셸 실행, 너무 쉽게.
중첩해도 전혀 변경되지 않습니다.


이제 "쉘이 왜 이런 일을 하는가"라는 질문에 대답한 후:
왜 이런 걸 물어보나요?

이것은 흥미로운 주제이지만 귀하의 목표가 무엇인지 완전히 이해하지 못합니다
.

  • 최적화된 bash 구현을 제안하시겠습니까?
  • 포크 수를 줄이시겠습니까? 성능상의 이유로? 어떤 미적인 이유로? 이는 독립적인 환경(주소 공간-프로세스 포함)을 제공하는 가장 빠른 방법입니다.
  • 쉘 구문을 변경하시겠습니까? 달성하려는 목표는 정확히 무엇입니까?

원하시면 다른 사람이 질문에 세부 정보를 추가하도록 요청하고 댓글을 남겨주세요.



~에서man bash

COMMAND EXECUTION ENVIRONMENT
       [ ... ]

       Command substitution, commands grouped with  parentheses,  and  asyn‐
       chronous  commands  are  invoked  in a subshell environment that is a
       duplicate of the shell environment, except that traps caught  by  the
       shell  are reset to the values that the shell inherited from its par‐
       ent at invocation.  Builtin commands that are invoked as  part  of  a
       pipeline  are  also executed in a subshell environment.  Changes made
       to the subshell environment cannot affect the shell's execution envi‐
       ronment.

       [ ... ]

관련 정보