다음을 수행하는 bash 스크립트가 필요합니다.
- wget을 사용하여 3개의 파일을 동시에 다운로드하면 동시에 완료할 필요가 없습니다.
- 동시에 3개의 다운로드를 취소할 수 있습니다
CTRL+C
(완료된 다운로드 제외).
현재 저는 wget -c URL
각 터미널에서 3개의 병렬 인스턴스를 실행하고 있습니다. 하지만 Linux 재부팅 후 계속할 수 있도록 사용자 입력이 취소되기를 기다리는 스크립트가 필요합니다.
내 시스템은 Cygwin이 설치된 Windows입니다.
답변1
parallel
이를 달성하기 위해 GNU를 사용할 수 있습니다 . URL을 배열에 넣고 다음 wget
을 실행합니다 parallel
.
#!/bin/bash
urls=( "https://example.com" "https://example1.com" "https://example2.com")
parallel wget -c ::: "${urls[@]}"
Parallel은 명령을 병렬로 실행하고 스크립트를 중지합니다(예: Ctrl+를 사용하면 C병렬 처리가 종료되고 완료된 인스턴스에 영향을 주지 않고 실행 중인 세 개의 wget 인스턴스가 모두 종료됩니다.
parallel
운영 체제 저장소에서 찾을 수 있어야 합니다 .
설치하고 싶지 않거나 설치할 수 없는 경우 parallel
bash에서 로컬로 설치할 수도 있습니다.
#!/bin/bash
trap 'kill $(jobs -p)' EXIT
urls=( "https://example.com" "https://example1.com" "https://example2.com" )
for url in "${urls[@]}"; do
wget -c "$url" &
done
wait
여기서의 비결은 trap
내장 함수( help trap
bash 참조)를 사용하여 다음을 수행하는 것 입니다.덫kill $(jobs -p)
EXIT 신호 명령. jobs -p
현재 셸의 모든 하위 프로세스의 PID가 반환되므로 이 경우 실행 중인 wget
프로세스의 PID가 됩니다. 이들은 kill
살해된 곳으로 전달됩니다. 따라서 스크립트를 종료하면 하위 스크립트로 전달됩니다. +kill 스크립트를 계속 사용하여 프로세스를 종료 wait
할 수 있도록 종료하기 전에 모든 백그라운드 작업 실행이 완료될 때까지 스크립트가 대기하는지 확인하십시오 .wget
CtrlC
답변2
Bash 스크립트는 다음 위치에 있습니다.이 다른 답변Bash가 별도의 프로세스 그룹에서 명령(비동기 명령 포함)을 실행하기 때문에 트랩이 필요합니다. 터미널은 전경 프로세스 그룹에 대해 알고 있으며 Ctrl해당 그룹에 +의 SIGINT를 보냅니다 c. Bash 스크립트가 wait
포그라운드에 있을 때 그 bash
자체는 포그라운드 프로세스 그룹에 속하지만 wget
자신이 생성한 프로세스 그룹에는 속하지 않습니다. SIGINT(있는 경우) 가 s bash
대신 도착합니다 wget
. 그렇기 때문에 위의 답변에 함정이 필요합니다.
다른 쉘은 다르게 작동할 수 있습니다. 내 쿠분투에서는 posh
새로운 프로세스 그룹이 생성되지 않으며 자신이 속한 프로세스 그룹의 모든 것을 실행합니다. 이 사실을 통해 스크립트를 단순화할 수 있습니다.
#!/usr/bin/posh
set -- 'https://example.com' 'https://example1.com' 'https://example2.com'
for url do
wget -c "$url" &
done
wait
스크립트가 전경에서 실행되는 동안 +를 누르면 Ctrl터미널은 SIGINT를 직접 전송합니다.cposh
그리고wget
포그라운드 프로세스 그룹과 동일한 프로세스 그룹에 있기 때문입니다 .
노트:
posh
배열은 지원되지 않으므로 URL을 위치 매개변수로 저장합니다. 해당set …
줄을 제거한 다음 스크립트를 호출할 때 URL(예:)을 지정할 수 있습니다./the_script 'https://example.com' 'https://example1.com' 'https://example2.com'
. 이렇게 하면 스크립트를 임의의 콘텐츠를 병렬로 다운로드하기 위한 도구로 바꿀 수 있습니다.- 트랩에 사용되는 또 다른 대답은
kill
기본 신호가 SIGTERM이며 이는 SIGINT와 동일하지 않습니다(wget
동일한 방식으로 반응할 수 있음).kill
SIGINT 또는 다른 신호를 보낼 수 있으며 선택 사항입니다(kill -s …
). 우리 스크립트에서는 선택의 여지가 없습니다. 우리는 어떤 신호도 전달하지 않으며 어떤 신호도 생성하지 않습니다. Ctrl먼저 c터미널에서 SIGINT를 스크립트를 해석하는 쉘뿐만 아니라 s에도 보내 도록 모든 것을 설정했습니다wget
.
다른 답변은 좋습니다. GNU가 parallel
올바른 도구이고 Bash가 trap
작동해야 하므로 어떤 의미에서는 제 답변이 필요하지 않습니다. 나는 여전히 Ctrl+가 어떻게 c작동하는지, 그리고 다양한 쉘이 어떻게 작동하는지 알면 원하는 동작을 얻기 위해 다른 쉘을 선택할 수 있다는 것을 보여주고 싶습니다 .