[bash] bash 스크립트에서 여러 프로그램을 병렬로 어떻게 실행합니까?

많은 프로그램을 실행 하는 .sh 파일 을 작성하려고 합니다. 동시에

나는 이것을 시도했다

prog1
prog2

그러나 그것은 prog1을 실행하고 prog1이 끝날 때까지 기다렸다가 prog2를 시작합니다 …

어떻게 병렬로 실행할 수 있습니까?



답변

prog1 &
prog2 &


답변

어때요?

prog1 & prog2 && fg

이것은 :

  1. 스타트 prog1 .
  2. 백그라운드로 보내지 만 출력물을 계속 인쇄하십시오.
  3. 시작 prog2하고 전경에 유지하면 다음과 같이 닫을 수 있습니다.ctrl-c .
  4. 때를 가까이 prog2, 당신에게 돌아갑니다 prog1‘의 전경 도 가까이 함께 할 수있는 당신은 그래서 ctrl-c.

답변

당신은 사용할 수 있습니다 wait:

some_command &
P1=$!
other_command &
P2=$!
wait $P1 $P2

백그라운드 프로그램 PID를 변수 ( $!마지막으로 시작된 프로세스 PID)에 할당 한 다음 wait명령이 대기합니다. 스크립트를 죽이면 프로세스도 죽이기 때문에 좋습니다!


답변

GNU Parallel http://www.gnu.org/software/parallel/을 사용하면 다음과 같이 쉽습니다.

(echo prog1; echo prog2) | parallel

또는 원하는 경우 :

parallel ::: prog1 prog2

더 알아보기:


답변

를 사용하여 여러 프로세스를 쉽게 실행하고 종료하려면 ctrl-c이것이 내가 가장 좋아하는 방법입니다. 하위 셸에서 여러 백그라운드 프로세스를 생성 (…)하고 trap SIGINT을 실행 kill 0하면 하위 셸 그룹에 생성 된 모든 것이 종료됩니다.

(trap 'kill 0' SIGINT; prog1 & prog2 & prog3)

복잡한 프로세스 실행 구조를 가질 수 있으며 모든 것이 단일으로 닫힙니다 ctrl-c(마지막 프로세스가 포 그라운드에서 실행되도록하십시오 (즉, &after를 포함하지 마십시오 prog1.3)).

(trap 'kill 0' SIGINT; prog1.1 && prog1.2 & (prog2.1 | prog2.2 || prog2.3) & prog1.3)


답변

xargs -P <n> 당신이 실행할 수 있습니다 <n>명령을 병렬 .

동안 -P 비표준 옵션이며, 모두 GNU (리눅스) 및 맥 OS / BSD 구현을 지원합니다.

다음 예제는

  • 실행 기껏해야 3 개의 명령을 병렬로
  • 이전에 시작된 프로세스가 종료 될 때만 추가 명령이 시작됩니다.
time xargs -P 3 -I {} sh -c 'eval "$1"' - {} <<'EOF'
sleep 1; echo 1
sleep 2; echo 2
sleep 3; echo 3
echo 4
EOF

결과는 다음과 같습니다.

1   # output from 1st command 
4   # output from *last* command, which started as soon as the count dropped below 3
2   # output from 2nd command
3   # output from 3rd command

real    0m3.012s
user    0m0.011s
sys 0m0.008s

타이밍은 명령이 병렬로 실행되었음을 나타냅니다 (마지막 명령은 원본 3 중 첫 번째가 종료 된 후에 만 ​​시작되었지만 매우 빠르게 실행 됨).

xargs모든 명령이 완료 될 때까지 명령 자체는 반환하지 않습니다,하지만 당신은 제어 연산자를 종료하여 백그라운드에서 그것을 실행할 수 &사용하여 다음과 wait전체 기다릴 내장을 xargs명령을 완료 할 수 있습니다.

{
  xargs -P 3 -I {} sh -c 'eval "$1"' - {} <<'EOF'
sleep 1; echo 1
sleep 2; echo 2
sleep 3; echo 3
echo 4
EOF
} &

# Script execution continues here while `xargs` is running 
# in the background.
echo "Waiting for commands to finish..."

# Wait for `xargs` to finish, via special variable $!, which contains
# the PID of the most recently started background process.
wait $!

노트 :

  • BSD / macOS xargs를 사용하려면 명령 수를 명시 적으로 병렬 로 실행 xargs해야 하지만 GNU 에서는 최대한 병렬 -P 0 실행 하도록 지정할 수 있습니다 .

  • 병렬로 실행되는 프로세스의 출력은 생성 될 때 도착 하므로 예기치 않게 인터리브 됩니다.

    • Ole의 답변 ( 대부분의 플랫폼에서 표준으로 제공 되지는 않음)parallel 에서 언급했듯이 GNU 는 프로세스별로 출력을 편리하게 직렬화 (그룹화)하고 더 많은 고급 기능을 제공합니다.

답변

#!/bin/bash
prog1 & 2> .errorprog1.log; prog2 & 2> .errorprog2.log

별도의 로그로 오류를 리디렉션하십시오.