파일에서 for 루프로 매개변수를 전달하고 병렬로 실행하고 각 매개변수에 대한 로그를 생성하는 방법

파일에서 for 루프로 매개변수를 전달하고 병렬로 실행하고 각 매개변수에 대한 로그를 생성하는 방법
for test in "${a[@]}"
do
    
    sh ansiblescript.sh -s $a

    if [[ $? -eq 0 ]]; then
        echo "Success"
    else
        echo "Failed"
        exit 1
    fi
done

다음 파일의 입력을 받아들이는 위의 for 루프가 있습니다.

테스트.txt

a b c d 

이제 먼저 실행된 a다음 으로 이동합니다 b. 네 가지를 모두 병렬로 실행하고 각각에 대해 별도의 로그 파일을 작성하고 싶습니다.

답변1

예를 들어, 테스트 스크립트가 주어지면

shell> cat ansiblescript.sh
timestamp=`date +"%b %d %H:%M:%S"`
printf "$timestamp ansiblescript.sh: started\n"
sleep 5
timestamp=`date +"%b %d %H:%M:%S"`
printf "$timestamp ansiblescript.sh: finished\n"
exit 0

다음 스크립트는 디렉토리를 생성합니다/tmp/ansible로그용. 그러면 파일 내용이테스트.txt분할되어 반복됩니다. 스크립트는 비동기적으로 실행됩니다. 바라보다비동기 작업 및 폴링.

shell> cat playbook.yml
- hosts: localhost
  gather_facts: false
  tasks:
    - file:
        state: directory
        path: /tmp/ansible

    - debug:
        msg: "{{ '%b %d %H:%M:%S'|strftime }} Sctipts started."

    - shell:
        cmd: "sh ansiblescript.sh -s {{ item }} >>
              /tmp/ansible/ansiblescript-{{ item }}.log"
      register: result
      async: 30
      poll: 0
      loop: "{{ lookup('file', 'test.txt')|split(' ') }}"

    - async_status:
        jid: "{{ item.ansible_job_id }}"
      loop: "{{ result.results }}"
      loop_control:
        label: "{{ item.item }} job_id={{ item.ansible_job_id }}"
      register: ap_result
      until: ap_result.finished
      retries: 30

    - debug:
        msg: "{{ '%b %d %H:%M:%S'|strftime }} Scripts finished."

    - debug:
        msg: "{{ (item.rc == 0)|ternary('Success', 'Failed') }}
              {{ item.start }}
              {{ item.end }}"
      loop: "{{ ap_result.results }}"
      loop_control:
        label: "{{ item.item.item }}"

주어진

shell> ansible-playbook playbook.yml

PLAY [localhost] ***********************************************************

TASK [file] ****************************************************************
ok: [localhost]

TASK [debug] ***************************************************************
ok: [localhost] => 
  msg: Apr 13 22:35:23 Sctipts started.

TASK [shell] ***************************************************************
changed: [localhost] => (item=a)
changed: [localhost] => (item=b)
changed: [localhost] => (item=c)
changed: [localhost] => (item=d)

TASK [async_status] ********************************************************
FAILED - RETRYING: [localhost]: async_status (30 retries left).
changed: [localhost] => (item=a job_id=881555332548.1994349)
changed: [localhost] => (item=b job_id=644490646974.1994376)
changed: [localhost] => (item=c job_id=859370052106.1994407)
changed: [localhost] => (item=d job_id=704644892779.1994438)

TASK [debug] ***************************************************************
ok: [localhost] => 
  msg: Apr 13 22:35:31 Scripts finished.

TASK [debug] ***************************************************************
ok: [localhost] => (item=a) => 
  msg: Success 2022-04-13 22:35:24.569468 2022-04-13 22:35:29.581256
ok: [localhost] => (item=b) => 
  msg: Success 2022-04-13 22:35:24.846117 2022-04-13 22:35:29.858153
ok: [localhost] => (item=c) => 
  msg: Success 2022-04-13 22:35:25.112447 2022-04-13 22:35:30.127829
ok: [localhost] => (item=d) => 
  msg: Success 2022-04-13 22:35:25.393390 2022-04-13 22:35:30.405189
PLAY RECAP *****************************************************************
localhost: ok=6 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

로그 파일 보기

shell> cat /tmp/ansible/ansiblescript-a.log 
Apr 13 22:35:24 ansiblescript.sh: started
Apr 13 22:35:29 ansiblescript.sh: finished
shell> cat /tmp/ansible/ansiblescript-b.log 
Apr 13 22:35:24 ansiblescript.sh: started
Apr 13 22:35:29 ansiblescript.sh: finished
shell> cat /tmp/ansible/ansiblescript-c.log 
Apr 13 22:35:25 ansiblescript.sh: started
Apr 13 22:35:30 ansiblescript.sh: finished
shell> cat /tmp/ansible/ansiblescript-d.log 
Apr 13 22:35:25 ansiblescript.sh: started
Apr 13 22:35:30 ansiblescript.sh: finished

답변2

&이 답변에 표시된 대로 백그라운드에서 프로세스를 사용하고 실행할 수 있습니다 .https://stackoverflow.com/a/3643961/1572593

sh ansiblescript.sh -s $a &

끊기 신호를 처리하기 위한 논리를 추가했을 수도 있습니다. 즉, 스크립트가 종료되고 프로세스가 계속 실행 중이면 어떤 일이 발생합니까? 이 분야의 연구도 wait마찬가지입니다 nohup.

답변3

GNU Parallel을 사용하면 다음과 같습니다:

parallel -j0 --result {}.out --joblog my.log sh ansiblescript.sh -s {} ::: "${a[@]}" || echo one or more failed

관련 정보