Makefile에서 bash 연관 배열 반복

Makefile에서 bash 연관 배열 반복
$ bash -version
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)

다음 쉘 스크립트를 고려하십시오.

#!/bin/bash

declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )

for key in "${!PROVS[@]}" ; do \
  touch "foo_${key}_${PROVS[${key}]}" ; \
done

Makefile에서 동등한 작업을 수행하려고 합니다.

SHELL := /bin/bash
.PHONY: foo
foo:
  declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )

  for key in "$${!PROVS[@]}" ; do \
    touch "foo_$${key}_$${PROVS[$${key}]}" ; \
  done

나는 아니에요진짜touch파일을 원합니다 . 할 수 없기 때문에 이 작업을 수행하고 있습니다 @echo. 루프에 있기 때문에 @가 줄의 시작 부분에 있는 것으로 간주되지 않습니다. 아니면 그런 일이 일어나고 있는 것 같습니다.

어쨌든 요점은 루프가 전혀 실행되지 않는 것 같아서 touch/ echo비즈니스가 발생한다는 것입니다. 위 셸 스크립트의 내용은 make터미널에 정확히 반영됩니다. 나는 shebang을 추가하고 온전한 점검으로 실행했습니다. 매력처럼 작동했습니다.

일반 배열을 사용하면 문제가 없습니다.

for prov in NL PE NS NB QC ON MB SK AB BC YK NT NU ; do \

하지만 이러한 코드(10, 11 등)도 필요합니다.

누구든지 이것에 대한 통찰력을 가지고 있습니까?

필요하지는 않지만 "declare -A"를 사용하면서 파일 상단에 PROVS 변수를 할당하는 방법(또는 가능한지)도 알고 싶습니다.

편집하다: 내가 Makefile 예제를 엉망으로 만들어서 단지 인라인 쉘 명령일 뿐이고 더 이상 레시피가 아닙니다. 명확한 설명을 위해 "foo:" 대상을 다시 추가했습니다.

답변1

발췌한 코드가 합리적으로 대표적인 경우 Bash 명령을 Makefile에 직접 입력하고 Make가 Bash를 사용하여 해당 명령을 실행하기를 기대하는 것으로 보입니다. 그런 일은 일어나지 않았습니다. Makefile의 구문은 완전히 다릅니다. 이내에레시피의 경우 Bash 명령을 입력할 수 있습니다. 레시피의 각 줄은 별도의 하위 쉘에서 실행됩니다. 따라서 최소한 두 가지 변경이 필요합니다.

  • 쉘 명령이 대상에 있어야 합니다.
  • declare루프와 동일한 셸에서 실행 해야 합니다 . 그렇지 않으면 declareBash 인스턴스에 있고 해당 인스턴스를 종료한 다음 현재 누락된 가 필요하지 않은 별도의 인스턴스에서 루프를 실행합니다 declare.

이는 이러한 변경 사항을 적용한 Makefile의 간단한 리팩토링입니다.

SHELL=/bin/bash   # This is the standard compliant method

.PHONY: all
all:
    declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 \
        ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 \
        ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )\
    ; for key in "$${!PROVS[@]}" ; do \
        touch "foo_$${key}_$${PROVS[$${key}]}" ; \
    done

데모:http://ideone.com/t94AOB

@명령을 자동으로 실행하는 규칙은 전체 명령줄에 적용됩니다. 따라서 위 항목 앞에 배치할 수 있으며 declare, 이 경우 전체 명령줄이 Bash에 제출되기 전에 제거됩니다. 다른 곳에서는 제거되거나 이해되지 않으며 호출 셸에서 Bash 구문 오류가 발생하는 것으로 보입니다.

(규칙에 대한 집착은 어쨌거나 @반패턴입니다 . make -s출력을 보고 싶지 않다면 실행하세요. 종료하면 make규칙 디버깅이 더 어려워질 뿐입니다.)

관련 정보