특정 파일을 찾고 각 파일에 대해 Python 스크립트를 실행하는 Makefile을 작성하고 싶습니다. Python 스크립트는 sys.stdin
입력을 허용합니다.
find $(W)/$(OVE) -name "*.xml" -print | \
while read x ; do \
cat $x | /opt/exp/bin/python2.7 process_results.py > $(W)/$(OVE)/$(dirname $x)_$(basename $x).xml \
done
출력은 $(dirname $x)_$(basename $x).xml
빈 _.xml 파일입니다.
명령줄에서 이 명령을 실행하면 제대로 작동하지만 Makefile에서는 작동하지 않습니다.
이 명령에 어떤 문제가 있는지 알려 주시겠습니까?
답변1
먼저, 쉘에서 해석한 대로 달러 기호를 인용해야 합니다. 실제로 $x
및 make에 의해 구문 분석 $(dirname $x)
됩니다 $(basename $x)
. while 루프 본문 끝에 세미콜론도 없습니다. make 실행 결과를 확인하면 쉘이 이에 대해 불평하는 것을 볼 수 있습니다.
find $(W)/$(OVE) -name "*.xml" -print | \
while read x ; do \
cat $$x | /opt/exp/bin/python2.7 process_results.py > $(W)/$(OVE)/$$(dirname $$x)_$$(basename $$x).xml; \
done
또 다른 가능한 문제는 $(dirname $x)
부품이 이미 포함되어 있다는 것입니다 $(W)/$(OVE)
. 예를 들어, $(W)
is foo
and $(OVE)
is bar
and $x
is 인 경우 아마도 작성하고 싶은 subdir/subsubdir/wibble.xml
유사한 파일을 작성하려고 시도하게 될 것입니다 . 파일을 파일로 변환하는 것도 이상합니다. 원래 확장자를 제거할 계획이라면 직접 작성해야 하지만, 다시 추가하기 위해 확장자를 제거할 필요는 없습니다. 따라서 다음과 같이 작성하고 싶을 수도 있습니다.foo/bar/foo/bar/subdir/subsubdir_wibble.xml.xml
foo/bar/foo/bar/subdir/subsubdir_wibble.xml.xml
.xml
.xml.xml
.xml
basename $$x .xml
find $(W)/$(OVE) -name "*.xml" -print | \
while read x ; do \
/opt/exp/bin/python2.7 process_results.py <$$x >$$(dirname $$x)_$$(basename $$x); \
done
또 다른 문제는 실행이 process_results.py
실패하면 make가 계속 실행되고 빌드가 성공한 것으로 보고된다는 것입니다. 오류가 발생하면 셸에 중지하라고 지시합니다.
set -e; \
find $(W)/$(OVE) -name "*.xml" -print | \
while read x ; do \
/opt/exp/bin/python2.7 process_results.py <$$x >$$(dirname $$x)_$$(basename $$x); \
done
답변2
$x
etc $(dirname $x)
... make는 그것들을 자신의 변수로 해석하기 때문에 make에 의해 모두 깨질 것입니다. 한 줄짜리 쉘 스크립트로 감싸서 Makefile에서 호출하는 것이 더 좋습니다.
답변3
쉘에 전달하는 달러 기호를 인용해야 합니다. 그렇지 않으면 make
쉘이 이를 해석하려고 시도할 것입니다.
-find $(W)/$(OVE) -name -print | \
while read x ; do \
cat $$x | /opt/exp/bin/python2.7 process_results.py \
> $(W)/$(OVE)/$$(dirname $$x)_$$(basename $$x).xml; \
done
단일 달러 기호는 변수 확장을 수행합니다. 이중 달러 기호는 단일 달러 기호로 명령줄에 전달됩니다.