함수를 통해 전역 변수 값 파이프 유지

함수를 통해 전역 변수 값 파이프 유지

나는 작은 bash 스크립트를 작성하고 sed일부 HTML 페이지에서 일부 URL을 추출하는 데 사용했습니다.

sed 결과를 변수로 가져와 매번 다시 읽는 것을 방지하기 위해 간단히 3개의 함수를 만들고 함께 파이프했습니다.

first_function $1 | second_function | third_function

다음과 같이 표현해 보겠습니다.

  • 첫 번째 함수는 주어진 목록에서 항목 URL을 찾습니다.링크 주소( $1)
  • 두 번째 함수는 각 파이프라인 URL에서 이미지를 추출합니다.src
  • 세 번째 함수는 출력 HTML을 조합합니다.

이제 이를 에코 $lot_url하여 HTML에 모두 넣을 second_function수 있습니다 .readthird_function$img_url

더 깨끗해질 것이다접근 가능한 전역 변수로 만들 수 있다면 second_function하지만 third_function나는 할 수 없는 것 같다.

이는 함수 간에 전달되는 값의 수가 증가할수록 더욱 필요해집니다.

전체 샘플 코드는 다음과 같습니다.

first_function(){
    curl -s "$1" | sed -nr '
        #extract sub urls
    '
}

second_function(){
    while read lot_url; do
        echo "$lot_url"
        curl -s "$lot_url" | sed -nr '
            #extract img src
        '
    done
}

third_function(){
    while read lot_url; read img_url; do
        echo "<a href="$lot_url"><img src="$img_url" /></a>"
    done
}

first_function "$1" | second_function | third_function

답변1

파이프의 양면은 서로 다른 프로세스에 있습니다. 이러한 프로세스 간에 변수를 공유할 수 없습니다. 데이터를 공유하려면 데이터를 파이프하거나 대체 통신 채널을 사용해야 합니다. 대체 통신 채널이 필요한 경우 셸의 기능을 넘어서는 경우 실제 프로그래밍 언어로 전환하세요.

여기에서는 두 번째 파이프라인에서 병렬화하는 것이 나 lot_url에게는 img_url좋은 해결책인 것 같습니다 . 나는 그것들을 같은 줄로 전달할 것입니다. URL이 올바르게 이스케이프되었다고 가정하면 특정 따옴표가 필요하지 않으며 두 따옴표를 같은 줄에 전달할 수 있습니다. 이는 img_url각각에 가변 개수의 s를 허용한다는 장점이 있습니다 lot_url.

second_function(){
    while read lot_url; do
        echo "$lot_url"
        curl -s "$lot_url" | sed -nr -e '
            #extract img src
        ' -e "s>^>$lot_url >"
    done
}

third_function(){
    while read lot_url img_url; do
        echo "<a href="$lot_url"><img src="$img_url" /></a>"
    done
}

답변2

여기서는 while 루프가 괜찮을 것 같아요. 어쨌든 반복할 때마다 실행 파일을 호출하기 때문에 실제로 차이가 있다고 생각하지 않습니다. 이 방법으로 당신은할 수 있는원하는 전역 변수를 공유하세요. 좋다:

source_cmd |
    while read var
    do  fn1 "$var" |
        fn2 "$var"
    done

하지만 워크플로를 약간 변경하는 것이 더 나을 것이라고 생각했습니다. 이 기능은 배열 기반 셸 명령 집합에 지나지 않습니다. 이제 이러한 배열을 사용하지 않으므로 명령 집합을 가리키는 일반적인 목적으로 사용해야 합니다. 제가 볼 수 있는 가장 일반적인 것은 입니다 curl ... | sed .... 인수를 취하는 함수로 만드세요. 따라서 결과는 다음과 같을 수 있습니다.

curl_sed() { url=$1 && shift
    curl -s "$url" | sed -nr "$*"
}
fn() { URL=$1 && shift
    set -- '#extract sub url sed script' \
           '#extract img src sed script'
    curl_sed "$URL" "$1" | 
        while read lot_url
        do  IFS='
';          printf '<a href="'"$lot_url"'"><img src="%s" /></a>\n' \
            $(curl_sed "$lot_url" "$2")
        done
}

당신은 이 질문에 대한 Giles의 대답을 받아들였습니다. 분명히 몇 년 전만 해도 저는 깨닫지 못했습니다.이건 또 다른 거야이것은 나와 비슷한 접근 방식을 보여주며 이 목적에 더 적합하다고 생각합니다.

관련 정보