bash는 C의 포크 ()와 유사한 포크를 지원합니까?


25

동일한 스크립트의 두 복사본이 실행되도록 한 지점에서 포크하려는 스크립트가 있습니다.

예를 들어 다음 bash 스크립트가 존재합니다.

echo $$
do_fork()
echo $$

이 bash 스크립트가 실제로 존재하면 예상되는 결과는 다음과 같습니다.

<ProcessA PID>
<ProcessB PID>
<ProcessA PID>

또는

<ProcessA PID>
<ProcessA PID>
<ProcessB PID>

"do_fork ()"대신 이런 종류의 출력을 얻거나 bash 스크립트가 C와 같은 포크를 수행하도록 할 수있는 것이 있습니까?

답변:


23

예. 포크는 철자가 &:

echo child & echo parent

혼란 스러울 수있는 것은 $$쉘 프로세스의 PID가 아니라 원래 쉘 프로세스 의 PID입니다 . 이런 식으로 만드는 요점은 $$쉘 스크립트의 특정 인스턴스에 대한 고유 식별자라는 것입니다. 스크립트 실행 중에 변경되지 않으며 $$동시에 실행되는 다른 스크립트 와 다릅니다 . 쉘 프로세스의 실제 PID를 얻는 한 가지 방법은 sh -c 'echo $PPID'입니다.

셸의 제어 흐름은 C와 동일하지 않습니다. C에서 작성하는 경우

first(); fork(); second(); third();

쉘에 해당하는 것은

after_fork () { second; third; }
first; after_fork & after_fork

간단한 쉘 형태 first; child & parent는 일반적인 C 관용구에 해당합니다.

first(); if (fork()) parent(); else child();

&그리고 $$존재하는 모든 Bourne의 스타일 쉘과 (t) CSH이 방식으로 작동합니다. $PPIDorignal Bourne 쉘에는 없었지만 POSIX에는 있습니다 (따라서 ash, bash, ksh, zsh 등).


3
그러나 그것은 기본적으로 포크가 아닌 "포크 + exec"입니다.
mattdm

@ mattdm : 어? &포크입니다, 관련된 exec가 없습니다. 포크 + 실행은 외부 명령을 시작할 때입니다.
Gilles 'SO- 악마 그만해'

@ mattdm : 아, 코리가 무엇을 받고 있는지 알 것 같습니다. 이 exec없지만 두 언어의 제어 흐름이 다릅니다.
Gilles 'SO- 악마 그만해'

1
@Gilles : bash 컨트롤 연산자 &는 주어진 명령이 실행되는 서브 쉘을 시작합니다. 포크 + exec. &선행 명령없이 실행할 수는 없습니다 .
mattdm

5
글쎄요, "포킹의 철자가 &"인 것이 사실이라면, 당신은 &그 자체로 줄을 line 수 있습니다. 그러나 당신은 할 수 없습니다. "포크 여기"를 의미하지는 않습니다. "서브 쉘의 백그라운드에서 이전 명령 실행"을 의미합니다.
mattdm

10

예,이를 subshells 라고 합니다. 괄호 안의 셸 코드는 하위 셸 (포크)로 실행됩니다. 그러나 첫 번째 쉘은 일반적으로 자식이 완료되기를 기다립니다. &터미네이터를 사용하여 비 동기화 할 수 있습니다 . 다음과 같이 실제로 작동하는지 확인하십시오.

#!/bin/bash

(sleep 2; echo "subsh 1")&
echo "topsh"

$ bash subsh.sh


5
괄호는 서브 쉘을 작성하지만, fork + wait입니다. &포크 만입니다. 하위 프로세스에서 둘 이상의 파이프 라인을 실행하려면 하위 프로세스를 작성하지 않고 그룹화를 수행하는 중괄호를 사용하는 것으로 충분합니다.{ sleep 2; echo child; } &
Gilles 'SO-Stop be evil'Feb

6

이 작업을 수행하는 기본 배쉬 (또는 다른 일반적인 * nix 셸) 방법은 없습니다. 비동기 적으로 다른 것을 수행하는 분기 된 프로세스를 생성하는 방법은 많이 있지만, fork () 시스템 호출의 정확한 의미를 따르는 것은 없다고 생각합니다.

일반적인 접근 방식은 최상위 스크립트가 원하는 작업을 수행하는 도우미를 생성하는 것입니다. 당신이 $0 $@ &하거나 무엇이든간에, 당신은 처음부터 다시 시작하고 어떻게 든 알아낼 필요가 있습니다.

나는 실제로 그 일을 할 수있는 몇 가지 영리한 방법을 생각하기 시작했습니다 ....

그러나 , 내 두뇌가 너무 빠져 들기 전에 꽤 좋은 규칙이라고 생각합니다. 쉘로 무언가를 쓰려고 노력하고 영리한 트릭으로 가득 차 있고 더 많은 언어 기능을 원한다면 전환 할 시간입니다. 실제 프로그래밍 언어로 .


2
bash의 구문이 잘 풀리지는 않지만 논란의 여지가 있지만 Perl 또는 Python의 더 우아한 데이터 구조 및 기능이 누락되었지만 bash는 도메인에서 얻을 수 있는 만큼 실제적 입니다. 그것은 도메인 특정 언어이며, 많은 경우에 파이썬보다 더 간결하고 간결합니다. 방대한 시스템을 관리 할 수 ​​있고 파이썬을 모를 수 있습니까? 예. 당신은 그렇게 할 수 있고 bash [프로그래밍]의 핥기를 몰라? 시도하고 싶지 않습니다. 30 년 동안의 셸 프로그래밍 후 나는 그것이 실제와 같다고 말합니다. 그리고 네, 저는 파이썬을합니다. 그러나 젊은이들을 혼동하지 마십시오.
Mike S

2
즉, 기술적으로 나는이 답변을 더 좋아합니다. "&"가 사용자의 질문에 대한 답이라고 말하면, "동일한 스크립트의 두 복사본이 실행되고있는 시점에서 포크"는 혼란 스러워요. bash 매뉴얼에 따르면 "&"의 기능은 "... 하위 쉘의 백그라운드에서 [given] 명령을 실행하는 것입니다." 명령을 종료해야하며 포크 (기술적으로는 Linux에서는 clone ())를 포함하지만이 시점에서 동일한 스크립트의 두 사본이 실행되고 있지 않습니다.
Mike S
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.