ls
다른 명령 (예 : echo, rsync) 의 결과를 사용하려고합니다 .
all:
<Building, creating some .tgz files - removed for clarity>
FILES = $(shell ls)
echo $(FILES)
그러나 나는 얻는다 :
make
FILES = Makefile file1.tgz file2.tgz file3.tgz
make: FILES: No such file or directory
make: *** [all] Error 1
echo $$FILES
, echo ${FILES}
및을 사용해 보았습니다 echo $(FILES)
.
답변
와:
FILES = $(shell ls)
아래에 들여 쓰기 all
는 빌드 명령입니다. 따라서 이것은 확장 된 $(shell ls)
다음 명령 실행을 시도합니다 FILES ...
.
만약 FILES
있어야하는데 make
변수이 변수는 레시피 부, 예를 들면 외부에 할당해야
FILES = $(shell ls)
all:
echo $(FILES)
물론 이는 .tgz 파일을 생성하는 명령을 실행 하기 전에FILES
“output from ls
” 으로 설정 된다는 것을 의미 합니다. ( Kaz가 지적했듯이 변수는 매번 다시 확장되므로 결국에는 .tgz 파일이 포함될 것입니다. 일부 FILES := ...
는 효율성 및 / 또는 정확성을 위해이를 피해야합니다. 1 )
만약 FILES
셸 변수가되어야하는 설정할 수 있지만 공백없이 따옴표로 묶은 shell-ese로 수행해야합니다.
all:
FILES="$(shell ls)"
그러나 각 줄은 별도의 셸에서 실행되므로이 변수는 다음 줄까지 유지되지 않으므로 즉시 사용해야합니다.
FILES="$(shell ls)"; echo $$FILES
쉘이 확장되기 때문에 이것은 모두 약간 어리석은 일입니다. *
(및 기타 셸 glob 표현식) 일입니다.
echo *
쉘 명령으로.
마지막으로, 일반적인 규칙 (이 예에는 실제로 적용되지 않음) : esperanto가 주석에서 언급했듯이 출력을 사용하는 ls
것은 완전히 신뢰할 수 없습니다 (일부 세부 정보는 파일 이름에 따라 다르며 때로는 버전에 따라 다릅니다 ls
. 일부 버전의 ls
출력 삭제 시도 일부 경우에). 따라서 l0b0 및 이상적인 메모 와 같이 GNU를 사용하는 경우 자체 내부의 모든 것을 사용 $(wildcard)
하고 $(subst ...)
수행 할 수 있습니다 make
( “파일 이름의 이상한 문자”문제 방지). ( sh
메이크 파일의 레시피 부분을 포함하는 스크립트에서 또 다른 방법은 find ... -print0 | xargs -0
공백, 줄 바꿈, 제어 문자 등이 넘어 가지 않도록하는 것입니다.)
1 GNU Make 문서는 POSIX ::=
가 2012 년 에 할당을 추가했다고 추가로 설명 합니다 . 나는 이것에 대한 POSIX 문서에 대한 빠른 참조 링크를 찾지 못했고 어떤 make
변형이 ::=
할당을 지원 하는지 직접 알지 못합니다 . 비록 GNU make가 오늘과 같은 의미로 :=
, 즉 확장과 함께 할당을 수행하지만.
참고 VAR := $(shell command args...)
또한 철자 할 수 있습니다 VAR != command args...
몇 가지에 make
모든 현대적인 GNU를 포함, 변형 및 BSD는 내가 아는 한 변종입니다. 이 다른 변형이없는 $(shell)
때문에 사용 VAR != command args...
이 모두 짧은있는 우수 하고 더 변종에서 작업.
답변
또한 torek의 답변 외에도 눈에 띄는 점은 느리게 평가 된 매크로 할당을 사용하고 있다는 것입니다.
당신이 GNU 메이크업에있어 경우, 사용하는 :=
대신 할당을 =
. 이 할당으로 인해 오른쪽이 즉시 확장되고 왼쪽 변수에 저장됩니다.
FILES := $(shell ...) # expand now; FILES is now the result of $(shell ...)
FILES = $(shell ...) # expand later: FILES holds the syntax $(shell ...)
=
할당 을 사용하면의 모든 단일 발생이 구문을 $(FILES)
확장 $(shell ...)
하여 쉘 명령을 호출 함을 의미합니다 . 이렇게하면 make 작업이 느리게 실행되거나 놀라운 결과가 발생할 수 있습니다.