$ ()가 서브 쉘입니까?


답변:


75

$(…)정의에 따른 서브 쉘 : 쉘 런타임 상태 ¹의 사본이며 서브 쉘에서 작성된 상태의 변경 사항은 상위에 영향을 미치지 않습니다. 서브 쉘은 일반적으로 새로운 프로세스 를 분기 하여 구현 되지만 일부 쉘은이를 최적화 할 수 있습니다.

변수 값을 검색 할 수있는 서브 쉘이 아닙니다. 변수에 대한 변경 사항이 부모에게 영향을 주면 하위 셸이 아닙니다. 부모 가 출력 을 검색 할 수 있는 서브 쉘입니다 . 로 작성된 서브 쉘 $(…)에는 표준 출력이 파이프로 설정되어 있으며, 상위 파이프는 해당 파이프에서 읽고 출력을 수집합니다.

서브 쉘을 작성하는 몇 가지 다른 구성이 있습니다. 나는 이것이 bash의 전체 목록이라고 생각한다.

  • 그룹화를 위한 서브 쉘 : 서브 쉘을 ( … )생성하고 종료 될 때까지 기다립니다. { … }구문 목적을 위해 순전히 명령을 그룹화하고 서브 쉘을 작성하지 않는 것과 대조하십시오 .
  • 배경 : … &서브 쉘을 작성하고 종료되기를 기다리지 않습니다.
  • 파이프 라인 : … | …왼쪽과 오른쪽에 각각 하나씩 두 개의 서브 쉘을 작성하고 둘 다 종료 될 때까지 기다립니다. 쉘은 파이프를 작성하고 왼쪽의 표준 출력을 파이프의 쓰기 끝에 연결하고 오른쪽의 표준 입력을 읽기 끝에 연결합니다. 일부 쉘 (ksh88, ksh93, zsh, lastpipe옵션이 설정되고 효과적인 bash )에서는 오른쪽이 원래 쉘에서 실행되므로 파이프 라인 구성은 하나의 서브 쉘 만 작성합니다.
  • 명령 대체 : $(…)(또한 철자법 `…`)는 표준 출력을 파이프로 설정하여 서브 쉘을 작성하고, 상위에서 출력을 수집 한 후 마지막 줄 바꿈을 빼고 해당 출력으로 확장합니다. (그리고 결과물은 더 쪼개지고 글 로빙 될 수 있지만, 그것은 또 다른 이야기입니다.)
  • 프로세스 대체 : <(…)표준 출력이 파이프로 설정된 서브 쉘을 작성하고 파이프 이름으로 확장합니다. 부모 (또는 다른 프로세스)는 파이프를 열어 서브 쉘과 통신 할 수 있습니다. >(…)표준 입력의 파이프와 동일하지만 파이프를 사용합니다.
  • Coprocess : coproc …서브 쉘을 작성하고 종료 될 때까지 기다리지 않습니다. 서브 쉘의 표준 입력 및 출력은 각각 파이프로 설정되며 부모는 각 파이프의 다른 쪽 끝에 연결됩니다.

¹ 별도의 셸을 실행하는 것과 달리 .


${...}답변에 포함시킬 수 있습니까?
— user1717828

3
뭐야? 왜? 변수 확장은이 질문과 원격으로 어떤 관계가 있습니까? 내 답변에 전체 쉘 매뉴얼을 포함시키지 않을 것입니다.
— Gilles 'SO- 악마 그만

1
변수 확장은이 질문과 원격으로 어떤 관계가 있습니까? 몰라요, 그게 내가 물었습니다 :-) 그래서 중괄호 대체는 괄호 괄호 대체와 같지 않습니다.
— user1717828

@ user1717828 : 변수 확장은 서브 쉘과 관련이 없습니다. 그것은 모두 별도의 메커니즘이며, 시작하는 경우 확실히 읽을 가치가 있습니다!
— 0xdd

1
@EnricoMariaDeAngelis 유일한 방법은 아니지만 가장 자연스러운 방법입니다. 다른 방법은 command | { read line; … }(쉘에 따라 line파이프 라인 이후에 여전히 사용 가능하거나 사용 불가능할 수 있음)입니다. 출력을 생성하는 명령이 입력을 읽는 쉘과 독립적으로 실행되어야하기 때문에 모든 방법에는 서브 쉘이 포함됩니다. 명령이 셸 내부에 순수하게 포함 된 경우 (쉘 구성 및 내장 만, 외부 명령은 없음), 셸은 하위 프로세스를 만들지 않지만 최적화 일 뿐이므로 여전히 하위 셸을 만듭니다.
— Gilles 'SO- 악마 그만

20

bash 버전 4.4의 bash (1) 매뉴얼 페이지, "EXPANSION"섹션, "명령 대체"하위 섹션에서 :

Bash command는 서브 쉘 환경에서 실행하여 확장을 수행한다 ...]



1
흥미롭게도 CentOS 7에서 bash맨 페이지에는 하위 셸 이 언급되어 있지 않습니다 Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.. 이것이 의도적 인 누락인지 궁금합니다.
— dr01

6
@ dr01 반대로, bash 4.4는 "subshell"이라는 단어를 포함하도록 해당 문장의 단어를 변경했습니다. 설명은 여러 가지 다른 구성이 서브 쉘이라고 명시 적으로 언급했지만 4.4까지는 명령 대체에 대해 명시 적으로 언급되지 않았습니다.
— Gilles 'SO- 악마 그만해'8

그러나 CentOS v7.4.1708 (대부분 최근) bash는 v4.2.46입니다.
— dr01

5

예, ( commands... )A는 bash실행됩니다 서브 쉘 commands...다른 프로세스에.

당신이 가진 유일한 차이점은 $( commands... )이 코드 부분의 실행 후 것입니다 commands...모든 것을 교체 commands...에 썼다 stdout.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.