다음에서 사용하고 싶습니다.월드 와이드 웹내 makefile의 전제 조건으로 :
local.dat: http://example.org/example.gz
curl -s $< | gzip -d | transmogrify >$@
원격 파일이 로컬 파일보다 최신인 경우 "변환"하고 싶습니다.만들다정상 작동.
그래요아니요캐시된 사본을 보관하고 싶습니다.example.gz- 파일이 커서 원시 데이터가 필요하지 않습니다. 가급적이면 파일을 모두 다운로드하지 않는 것이 좋습니다. 목표는 make 플래그를 사용하여 일부를 병렬로 처리하는 것입니다 -j
.
이 문제를 해결하는 깨끗한 방법은 무엇입니까? 여러 가지 방법을 생각해 볼 수 있습니다.
- 빈 더미 파일을 유지하고 대상이 다시 생성될 때마다 업데이트합니다.
- GNU make를 사용하는 일부 플러그인새로운 플러그인 시스템(나는 이것에 대해 아무것도 모른다)
- 로컬 파일 시스템에 HTTP 서버를 설치하는 불가지론적인 방법
더 자세히 알아보기 전에 몇 가지 조언, 바람직하게는 구체적인 예를 듣고 싶습니다!
답변1
Makefile에서 다음과 같이 시도해 보세요.
.PHONY: local.dat
local.dat:
[ -e example.gz ] || touch -d '00:00' example.gz
curl -z example.gz -s http://example.org/example.gz -o example.gz
[ -e $@ ] || touch -d 'yesterday 00:00' $@
if [ "$(shell stat --printf '%Y' example.gz)" \
-gt "$(shell stat --printf '%Y' $@)" ] ; then \
zcat example.gz | transmogrify >$@ ; \
fi
truncate -s 0 example.gz
touch -r $@ example.gz
(참고: 이것은 Makefile이므로 들여쓰기는 공백이 아니라 탭입니다. 물론 연속된 줄에 후행 공백이 없거나 \
백슬래시 이스케이프를 제거하고 거의 읽을 수 없는 긴 줄로 만드는 것도 중요합니다.)
이 GNU make
레시피는 먼저 이름이 지정된 파일이 example.gz
존재하는지 확인하고( 에서 사용할 것이므로 ) -z
존재하지 않으면 curl
파일을 생성합니다 . touch
터치로 생성된 타임스탬프는 00:00(당일 오전 12시)입니다.
그런 다음 ( ) curl
옵션을 사용하여 마지막 다운로드 이후 수정된 콘텐츠만 다운로드합니다. 실제 날짜 표현이나 파일 이름이 주어질 수 있습니다. 파일 이름이 주어지면 파일의 수정 시간을 시간 조건으로 사용합니다. -z
--time-cond
example.gz
-z
나중에 존재하지 않는 경우 보장된 타임스탬프를 사용 local.dat
하여 생성됩니다.touch
나이가 많은보다 example.gz
. mtime 타임스탬프를 얻으 local.dat
려면 다음 명령이 존재해야 하기 때문에 이는 필요합니다 stat
.
그런 다음 example.gz
타임스탬프가 local.dat
그보다 최신이면 출력을 example.gz
파이프를 통해 리디렉션합니다 .transmogrify
local.dat
마지막으로 장부 및 정리 작업을 수행합니다.
- 잘립니다
example.gz
(전체 파일이 아닌 타임스탬프만 유지하면 되므로). touch
즉example.gz
, 동일한 타임스탬프를 갖게 됩니다.local.dat
.PHONY 대상은 local.dat
해당 이름의 파일이 이미 존재하더라도 대상이 항상 실행되도록 보장합니다.
원래 버전이 작동하지 않았으며 그 이유를 댓글에서 지적해 주신 @Toby Speight에게 감사드립니다.
transmogrify
또는 먼저 파일 시스템에 다운로드하지 않고 파일을 직접 파이프하려는 경우 :
.PHONY: local.dat
local.dat:
[ -e example.gz ] || touch -d '00:00' example.gz
[ -e $@ ] || touch -d 'yesterday 00:00' $@
if [ "$(shell stat --printf '%Y' example.gz)" \
-gt "$(shell stat --printf '%Y' $@)" ] ; then \
curl -z example.gz -s http://example.org/example.gz | transmogrify >$@ ; \
fi
touch -r $@ example.gz
노트:이는 대부분 테스트되지 않았으므로 구문을 완전히 수정하려면 약간의 변경이 필요할 수 있습니다. 여기서 중요한 것은 복사-붙여넣기 카고-컬트 솔루션이 아니라 접근 방식입니다.
나는 수십 년 동안 이 접근 방식의 변형(예: touch
타임스탬프 파일) 을 사용해 왔습니다. make
그것은 작동하며 일반적으로 sh에서 내 종속성 해결 코드를 작성하는 것을 피할 수 있습니다(비록 stat --printf %Y
여기서 비슷한 작업을 수행해야 했지만).
make
이것이 소프트웨어 컴파일을 위한 훌륭한 도구라는 것은 모두가 알고 있습니다 . 제 생각에는 시스템 관리 및 스크립팅 작업을 위한 도구로서 심각하게 과소평가된 도구이기도 합니다.
답변2
또 다른 대안은 종속성 체크섬을 사용하여 재구축을 트리거할지 여부를 결정하는 빌드 시스템을 사용하는 것입니다. 나는 종종 Gnu Make의 "터치" 트릭을 사용하지만 동적 종속성을 지정할 수 있고 변경되지 않는 파일이 재빌드를 트리거하지 않으면 훨씬 더 간단합니다. 다음은 사용 예입니다.하오메이케:
#! /usr/local/goodmake.py /bin/sh -se
#! *.date
# Get the last-modified date
curl -s -v -X HEAD http://${1%.date} 2>&1 | grep -i '^< Last-Modified:' >$1
#? local.dat
site=http://example.org/example.gz
$0 $site.date
curl -s $site | gzip -d | transmogrify >$1