동일한 터미널에서 한 번에 병렬 여러 명령 실행


81

Ctrl-C를 누를 때까지 각 명령이 종료되지 않는 몇 가지 명령을 실행하고 싶습니다. 한 번에 모두 실행하기 위해 실행할 수있는 것이 있습니까? Ctrl-C를 누르면 모두 종료됩니다. 터미널 출력을 공유 할 수 있습니다.

특히, 나침반 컴파일러, 커피 스크립트 컴파일러 및 파일 변경 사항을 감시하는 모든 파일 변경 사항을 감시하는 사용자 지정 명령이 있습니다. 각 명령에 대해 터미널을로드하고 싶지 않습니다.

답변:


123

이 bash 스크립트는 N 병렬 스레드 용입니다. 각 인수는 명령입니다.

trapSIGINT가 잡히면 모든 하위 프로세스를 종료합니다.
wait $PID_LIST각 프로세스가 완료되기를 기다리고 있습니다. 모든 프로세스가 완료되면 프로그램이 종료됩니다.

#!/bin/bash

for cmd in "$@"; do {
  echo "Process \"$cmd\" started";
  $cmd & pid=$!
  PID_LIST+=" $pid";
} done

trap "kill $PID_LIST" SIGINT

echo "Parallel processes have started";

wait $PID_LIST

echo
echo "All processes have completed";

이 스크립트를 다른 이름으로 저장 parallel_commands하고 실행 가능하게 만드십시오.
이 스크립트를 사용하는 방법은 다음과 같습니다.

parallel_commands "cmd arg0 arg1 arg2" "other_cmd arg0 arg2 arg3"

예:

parallel_commands "sleep 1" "sleep 2" "sleep 3" "sleep 4"

4 병렬 절전을 시작하고 "sleep 4"가 완료 될 때까지 기다립니다.


3
아주 멋지다. 함정은 내가 찾던 것입니다. wait불필요한 "process x exited"메시지를 억제하는 을 포함하도록 답변을 편집했습니다 .
Oliver Zheng

1
@MTsoul wait은 while 루프보다 낫습니다. 귀하의 제안으로 스크립트를 개선했습니다. 이제 N 병렬 명령에서도 작동합니다.
알레산드로 Pezzato

하나의 별개의 코어에서 각 cmd를 실행하는 것은 어떻습니까? 다음과 같이 실행해야합니까? ./parallel_commands "taskset -c 0 cmd arg0 arg1 arg2" "taskset -c 1 other_cmd arg0 arg2 arg3"또는 taskset -c 2 ./parallel_commands "taskset -c 0 cmd arg0 arg1 arg2" "taskset -c 1 other_cmd arg0 arg2 arg3 "
user2517676 2013-09-04

그래서 큰. 이제 bash 스크립에있는 몇 가지 명령이 있고 병렬 로 실행하고 싶 습니까?
shgnInc 2013

1
STDOUT 또는 종료 값을 원하십니까?
Alessandro Pezzato 2014 년

90

@ alessandro-pezzato의 의견을 기반으로합니다. 다음을 사용하여 여러 명령 실행& 사이 .

예:

$ sleep 3 & sleep 5 & sleep 2 &

백그라운드에서 명령을 실행합니다.


2
이것이 제가 찾던 것입니다.
TWR Cole

1
안녕하세요 @OleTange, 차이점을 모르겠습니다. 나는 시도 &!했고 &둘 다 동등하게 일했습니다.
nsantana 2017-06-30

조언 해 주셔서 감사합니다. 코드를 변경하고 느낌표를 제거합니다.
nsantana

2
Control-C는 이와 같이 실행될 때 모든 병렬 명령을 완전히 종료하지 않으며 백그라운드에서 계속 실행됩니다. 모든 명령 실행을 종료하는 올바른 방법은 무엇입니까?
Cal S

1
fg를 실행하고 Ctrl + C를 누르고 필요에 따라 반복합니다
KTibow

35

GNU 병렬 사용 :

(echo command1; echo command2) | parallel
parallel ::: command1 command2

죽이려면 :

parallel ::: command1 command2 &
PID=$!
kill -TERM $PID
kill -TERM $PID

1
@Oatman : 그래야하지만 GNU 병렬이 모든 배포판에있는 것은 아닙니다. 예를 들어 RHEL 7에는 즉시 사용할 수있는 패키지가없는 것 같습니다.
Stefan Majewsky

여러 프로세스를 시작하고 부모 병렬을 종료하여 모두 종료하는 병렬 프로세스의 PID를 추적 할 수 있습니까?
WM

@StefanMajewsky : parallelEPEL 저장소에 있습니다.
Onnonymous

인용 경고 / 노이즈는 정말 짜증납니다! 그것은 출력을 오염시킵니다. 당신은 그것을 침묵시킬 수 있습니다. 그러나 도대체 왜 이것을해야합니까? 모든 오픈 소스 도구가이 작업을 수행했다면 혼란을 상상해보십시오!
실용적인 괴짜

@JavadSadeqzadeh 당신이 읽을나요 git.savannah.gnu.org/cgit/parallel.git/tree/doc/...
올레 단게

3

간단한 Makefile로 수행 할 수 있습니다.

sleep%:
        sleep $(subst sleep,,$@)
        @echo $@ done.

-j옵션을 사용하십시오 .

$ make -j sleep3 sleep2 sleep1
sleep 3
sleep 2
sleep 1
sleep1 done.
sleep2 done.
sleep3 done.

-j옵션이 없으면 직렬로 실행됩니다.

$ make -j sleep3 sleep2 sleep1
sleep 3
sleep3 done.
sleep 2
sleep2 done.
sleep 1
sleep1 done.

`-n '옵션을 사용하여 드라 이런을 수행 할 수도 있습니다.

$ make -j -n sleep3 sleep2 sleep1
sleep 3
sleep 2
sleep 1

1

방금 작성한 훨씬 더 간단한 유틸리티를 제안하고 있습니다. 현재는 par라고 불리지 만 곧 parl 또는 pll로 이름이 변경 될 예정이며 아직 결정되지 않았습니다.

https://github.com/k-bx/par

API는 다음과 같이 간단합니다.

par "script1.sh" "script2.sh" "script3.sh"

접두사 명령은 다음을 통해 수행 할 수 있습니다.

par "PARPREFIX=[script1] script1.sh" "script2.sh" "script3.sh"

1
gnu parallel을 사용하여 위에서 설명한 작업을 시도했지만 실패한 후 유틸리티를 사용하여 첫 번째 시도에서 성공했습니다. 잘 했어!
worldsayshi

첫 번째 : parallel ::: "script1.sh" "script2.sh" "script3.sh"두 번째는 일반적으로 --tag : parallel --tag ::: "script1.sh" "script2.sh" "script3.sh"
Ole Tange

-13

여러 명령을 실행하려면 다음 &&과 같이 두 명령 사이에 추가 하십시오.command1 && command2

두 개의 다른 터미널에서 실행하려면 다음과 같이하십시오.

gnome-terminal -e "command1" && gnome-terminal -e "command2"

이 2 개 단자을 열 command1command2 그들 내에서 실행한다.

도움이 되었기를 바랍니다.


4
이것은 올바르지 않습니다. 성공한 command2 후에 command1 만 실행됩니다 command1. 시도 sleep 3 && sleep 3하면 6 초가 걸립니다.
Mark Setchell 2017-06-03

command1 && command2는 한 번에 실행을 시작하지 않습니다. 차례로 실행됩니다 (명령에 대한 성공 시나리오 고려).
Gahan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.