$ ()가 서브 쉘입니까?


답변:


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.