헤드가 완료되면 컬, xargs 파이프라인의 이전 단계를 중단합니다.

헤드가 완료되면 컬, xargs 파이프라인의 이전 단계를 중단합니다.

나는 여러 웹페이지를 다운로드하려고 하는데, N줄의 html을 다운로드하고 나면 모든 것을 중단하고 싶습니다. 그러나 대신 파이프라인의 이전 단계가 계속됩니다. 문제를 확인하는 예:

for i in /accessories /aches-pains /allergy-hayfever /baby-child /beauty-skincare; do echo $i; sleep 2; done | \
while read -r line; do curl "https://www.medino.com$line"; done \
 | head -n 2

이제 요청한 다음 중단하고 싶습니다.

그러나 실제로 일어나는 일은 다음과 같습니다.

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0<!DOCTYPE html>
<html lang="en" >
100  4412    0  4412    0     0  12788      0 --:--:-- --:--:-- --:--:-- 12751
curl: (23) Failed writing body (0 != 2358)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2358    0  2358    0     0   3772      0 --:--:-- --:--:-- --:--:--  3766
curl: (23) Failed writing body (0 != 2358)

( ^ repeats 4 times)

스크립트가 즉시 중단되지 않고 계속 실행되는 이유는 무엇입니까? 저는 배관에 대한 전문가가 아니기 때문에 여기에 기본적인 것이 빠진 것 같습니다.

답변1

파이프라인의 두 번째 부분은 입니다 while read -r line; do curl ...$line; done. 실행 시:

  1. 첫 번째 반복에서 쉘은 첫 번째 값을 라인으로 읽고 컬을 실행합니다. 컬(가져오기 및)은 head -n2처음 두 라인을 추출하고 종료하여 두 번째와 세 번째 부분 사이의 간격을 닫습니다. 귀하의 예에서 컬은 이 출력을 최소한 두 개의 블록에 기록하므로 두 번째 쓰기에서 오류가 발생하고 실패합니다. 즉, 0이 아닌 상태로 종료됩니다.

  2. 쉘은 명령이 실패할 때 대부분의 명령 시퀀스(복합 명령 포함)를 종료하지 않으며 쉘은 대화식으로 사용되는 경우가 많기 때문에 명령을 실행할 때마다 쉘이 죽어 다시 로그인해야 하는 경우 문제가 될 수 있습니다. 다시 시작하세요. 매우 불편합니다. 프로그램을 실행하는 동안 오류가 발생했습니다.

  3. 따라서 쉘은 두 번째 값을 라인으로 읽고 두 번째 컬을 실행합니다. 이는 파이프가 닫혀 있기 때문에 즉시 실패하지만 쉘은 다시 세 번째 라인을 읽고 세 번째 컬을 실행하는 방식으로 입력 End가 read실패할 때까지 계속됩니다. read이는 list-1 섹션에 있으며 while실패하면 루프가 종료됩니다.

다음을 사용하여 컬이 실패하고 종료되는지 명시적으로 테스트할 수 있습니다.

generate_values | while read -n line && curl ...$line; do :; done | head -n2

또는 쉘 옵션을 설정하여하다실패 시 종료:

generate_values | { set -e; while read -n line; do curl ...$line; done } | head -n2

두 가지 방법 모두 실행될 수 있습니다.하나컬은 쓰기 시에만 오류를 보고하기 때문에 종료됩니다.뒤쪽에파이프가 닫혀 있습니다. 즉, 마지막 블록 이후입니다. 컬 #2 출력의 마지막 블록 중에 출력 제한( head -n$n)이 소진되면 해당 컬은 "성공적으로" 종료되고 쉘은 컬 #3을 시작합니다. 이는 쓰기 중 처음(또는 유일한) 실패가 됩니다. .

관련 정보