여러 개의 bash 스크립트를 호출하고 순차적으로 실행하지 않고 병렬로 실행


19

: 나는 bash는 스크립트를 세 가지 (또는 그 이상)한다고 가정하자 script1.sh, script2.sh하고 script3.sh. 이 세 스크립트를 모두 호출하고 병렬로 실행하고 싶습니다 . 이를 수행하는 한 가지 방법은 다음 명령을 실행하는 것입니다.

nohup bash script1.sh &
nohup bash script2.sh &
nohup bash script3.sh &

(일반적으로 스크립트를 완료하는 데 몇 시간 또는 며칠이 걸릴 수 nohup있으므로 콘솔을 닫아도 계속 실행되도록 사용 하고 싶습니다 .)

그러나 단일 호출 과 동시에 세 가지 명령을 실행할 수있는 방법이 있습니까?

나는 뭔가를 생각하고 있었다

nohup bash script{1..3}.sh &

그러나 이것은 실행 표시 script1.sh, script2.shscript3.sh하지 병렬 시퀀스.


2
"단일 전화"는 무엇을 의미합니까?
jw013

1
사용 사례는 무엇입니까? 시작할 백만 개의 스크립트가 있습니까?
l0b0

@ jw013 하나의 짧은 줄 명령과 같은 것을 의미합니다. 시작할 스크립트가 100 개인 경우 입력하는 대신 짧은 (예 : nohup bash script{1..100}.sh &또는 for i in {1..100}; do nohup bash script{1..100} &; done) 를 입력하고 싶습니다nohup bash script*.sh & 100 개의 다른 시간을 .
Andrew

1
스크립트에 유용한 출력이있는 경우 : screentmux 콘솔 문제를 해결하지만 출력 (및 입력)에 계속 액세스하려면 (또는 ) .
Hauke ​​Laging

1
이러한 명령을 모두 같은 줄에 입력하지 못하게하는 것은 없습니다. nohup ... & nohup ... & nohup ... &. 대신 각 스크립트 이름을 개별적으로 입력하지 않고 모든 스크립트를 실행하려는 경우 간단한 루프가 수행합니다.
jw013

답변:



14

더 좋은 방법은 GNU Parallel 을 사용하는 것 입니다. GNU 병렬은 단순하며이를 통해 작업에 대한 더 많은 제어와 함께 병렬로 실행할 작업 수를 제어 할 수 있습니다.

아래 명령에서 script{1..3}.sh확장 bash되어 동시에 인수로 전송됩니다 . 여기서는 -j0가능한 많은 작업을 실행해야 함을 나타냅니다. 기본적으로 parallel하나의 CPU 코어에 대해 하나의 작업을 실행합니다.

$ parallel -j0 bash :::: <(ls script{1..3}.sh)

그리고 당신도 사용할 수 있습니다

$ parallel -j0 bash ::: script{1..3}.sh

두 번째 방법을 실행하는 동안 오류 메시지가 표시되면 --tollef 옵션이 설정되어 /etc/parallel/config있으며 삭제해야하며 모든 것이 잘 작동한다는 의미입니다.

GNU Parallels맨 페이지를 읽을 수 있습니다더 풍부한 옵션을 보려면 여기 에서 .

또한 원격 시스템에서 작업을 실행중인 경우 screen네트워크 문제로 인해 세션이 닫히지 않도록 사용하는 것이 좋습니다 . nohupbash의 최신 버전과 함께 제공 huponexit되므로 off부모 쉘 HUP이 종료 중에 자식으로 신호를 보내지 못하게됩니다 . 설정되지 않은 경우

$ shopt -u huponexit  

bash쉘 을로 사용할 parallel -j0 bash :::: <(ls script{1..3}.sh)수 있다면로 줄일 수 있습니다 parallel -j0 bash :::: script{1..3}.sh.
iruvar

'::::'를 병렬로 사용하는 경우 인수가 명령 자체가 아니라 실행할 명령이 포함 된 파일임을 의미합니다. 여기에서는 프로세스 대체를 사용하여 파일 설명자 내에서 스크립트 이름을 리디렉션합니다.
Kannan Mohan

어 .. 그렇다면 왜 안 되겠 어 parallel -j0 bash ::: script{1..3}.sh?
iruvar

이 아닌 bash ::: script{1..3}.sh에 전달되고 있습니다. 이 처음으로 확장한다 그래서 쉘과 그때까지 의 호출 , , . 나는 그것을 시도parallel::: script{1..3}.shparallel bash ::: script1.sh script2.sh script3.shparallelbash script1.shbash script2.shbash script3.sh
iruvar

1
아니요 혼란스럽지 않습니다. OP의 문제가 더 잘 해결된다는 parallel -j0 bash ::: script{1..3}.sh::::입니다. 프로세스 대체가 필요하지 않기 때문에 접근 방식 보다 낫습니다 . 또한 구문 분석 ls 출력은 함정으로 쟁이
iruvar

9

xargs여러 스크립트를 병렬로 실행할 수도 있습니다 .

$ ls script{1..5}.sh|xargs -n 1 -P 0 bash

여기서 각 스크립트는 인수로 bash에 개별적으로 전달됩니다. -P 0병렬 프로세스의 수가 가능한 많을 수 있음을 나타냅니다. bash default를 사용하는 것이 더 안전합니다 job control feature (&).


5

단일 회선 솔루션 :

$ nohup bash script1.sh & nohup bash script2.sh & nohup bash script3.sh &

덜 까다로워서 래퍼 스크립트를 사용하십시오.

$ cat script.sh
#!/usr/bin/env bash
script1.sh &
script2.sh &
script3.sh &
$ nohup script.sh &

또는 그것들을 반복하십시오 :

for script in dir/*.sh
do
    nohup bash "$script" &
done

2

타이핑 노력을 아끼고 싶다면

eval "nohup bash "script{1..3}.sh" &"

아니면 다시 생각할 수도 있지만


1

이 도구를 확인하십시오 : https://github.com/wagoodman/bashful

당신이 mytasks.yaml가진 말

tasks:
    - name: A title for some tasks
      parallel-tasks:
        - cmd: ./script1.sh
        - cmd: ./script2.sh -x an-arg
        - cmd: ./script3.sh -y some-other-arg

그리고 당신은 그렇게 실행합니다 :

nohup bashful run mytasks.yaml

스크립트는 수직 진행률 표시 줄과 병렬로 실행됩니다 (이전에 실행했으며 시간이 결정적인 경우 + eta). 주어진 3 개 이상을 실행하기 시작하면 병렬로 실행할 작업 수를 조정할 수 있습니다.

config:
    max-parallel-commands: 6
tasks:
    ...

면책 조항 : 나는 저자입니다.


0

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

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

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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.