동일한 스크립트의 두 복사본이 실행되도록 특정 시점에 분기하려는 스크립트가 있습니다.
예를 들어 다음 bash 스크립트가 존재할 것으로 예상합니다.
echo $$
do_fork()
echo $$
이 bash 스크립트가 존재하는 경우 예상되는 출력은 다음과 같습니다.
<ProcessA PID>
<ProcessB PID>
<ProcessA PID>
또는
<ProcessA PID>
<ProcessA PID>
<ProcessB PID>
이런 종류의 출력을 얻거나 bash 스크립트가 C와 유사한 포크를 수행하도록 하기 위해 "do_fork()" 대신 사용할 수 있는 것이 있습니까?
답변1
예. 포크의 철자는 다음과 같습니다 &
.
echo child & echo parent
혼란스러울 수 있는 점은 이것이 $$
쉘 프로세스의 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에서 이러한 방식으로 존재하고 작동합니다. $PPID
원래 Bourne 셸에는 없지만 POSIX(따라서 ash, bash, ksh, zsh 등)에는 있습니다.
답변2
응, 그거라고 해서브쉘. 괄호 안의 쉘 코드는 서브쉘(포크)로 실행됩니다. 그러나 첫 번째 셸은 일반적으로 하위 프로세스가 완료될 때까지 기다립니다. 종결자를 사용하여 비동기화할 수 있습니다 &
. 아래에서 실제로 작동하는 모습을 확인하세요.
#!/bin/bash
(sleep 2; echo "subsh 1")&
echo "topsh"
$ bash subsh.sh
답변3
이를 수행하는 기본 bash(또는 내가 아는 한 다른 일반적인 *nix 셸) 방법은 없습니다. 다른 작업을 비동기적으로 수행하기 위해 분기된 프로세스를 생성하는 방법에는 여러 가지가 있지만, 저는 fork() 시스템 호출의 정확한 의미를 따르는 것이 없다고 생각합니다.
일반적인 접근 방식은 분할하려는 작업만 수행하는 도우미를 최상위 스크립트에서 생성하도록 하는 것입니다. 이 작업을 수행하거나 $0 $@ &
무엇이든 수행하면 처음부터 시작하게 되며 어떻게든 이 문제를 해결해야 합니다.
실제로 저는 이를 수행하는 몇 가지 영리한 방법을 생각하기 시작했습니다.
하지만, 내 두뇌가 이것으로 너무 휩쓸리기 전에 좋은 규칙은 다음과 같습니다. 셸에서 무언가를 작성하려고 하는데 영리한 트릭으로 가득 차 있고 언어의 더 많은 기능을 원한다면 프로그래밍 언어를 전환해야 합니다. 이런 기능을 가지고 있습니다.