내 빌드 파일:
all: ...(other rules) clean
clean:
rm $(find . -type f -executable)
clean
위의 Makefile에서 규칙을 제거하면 모든 것이 예상대로 작동합니다. 추가되면 make
(또한 make clean
) 명령의 결과는 다음과 같습니다.
rm
rm: missing operand
Try 'rm --help' for more information.
make: *** [Makefile:46: clean] Error 1
여기서 문제의 원인은 무엇이며 해결 방법은 무엇입니까?
답변1
몇 가지 질문이 있습니다.
Makefile의 $ 기호를 쉘에 전달
명령을 실행하고 싶습니다
rm $(find . -type f -executable)
쉘이 명령 대체를 수행하도록 하십시오. 이렇게하려면 다음을 작성해야합니다.
clean:
rm $$(find . -type f -executable)
에서 사용하는 달러만큼 그 자체를 두 배로 만듭니다 $
.
"정리"할 것이 없는 상황 처리
출력이 find
비어 있으면 명령 대체 후
rm $(find . -type f -executable)
~이 되다
rm
일반적인 rm
명령은 무엇을 삭제할지 알려주지 않았다고 불평합니다. 이 문제를 해결하는 한 가지 방법은 을 사용하여 xargs
출력을 처리하는 것입니다 find
. 출력이 있으면 find
출력이 있는 경우 이를 청크로 나누고 rm을 실행합니다.
clean:
find . -type f -executable | xargs rm
파일 이름의 임의 문자 처리
Unix 파일 이름은 문자로 구분된 구성 요소로 구성됩니다 /
. 구성 요소 자체는 /
NUL 및 NUL을 제외한 모든 문자 시퀀스일 수 있습니다. 특히 구성 요소에는 줄 바꿈, 공백, 탭 등이 포함될 수 있습니다 *
.
명령 대체( )의 경우 rm $(find . -type f -executable)
쉘은 find의 출력을 처리합니다. 따라서 공백 문자로 인해 단어 분할이 발생하고, *
문자로 인해 파일 이름 "globbing"이 발생하는 등의 현상이 발생합니다. 합리적인 구현을 위해서는 xargs
이러한 상황을 피해야 합니다.
파일 이름이 then 으로 시작하면 -
명령 rm
에 대한 옵션으로 처리될 수 있습니다. 이를 방지하는 쉬운 방법은 --
"옵션 끝"을 표시하는 명령을 추가하는 것입니다.
남은 주요 문제는 줄 바꿈입니다. 입력을 개행 문자로 분할합니다. 따라서 호출된 파일이 xargs
있으면 출력이abc\ndef
find
abc
def
xargs
2개의 파일 rm
이름 abc
과 def
.
이 문제를 해결하려면 줄 바꿈 문자 대신 파일 이름에 표시할 수 없는 문자 1개(NUL)를 구분 기호로 지정하여 사용하십시오 find
.xargs
clean:
find . -type f -executable -print0 | xargs -0 rm --
find
당신이 지원하는 경우 최고의 솔루션
clean:
find . -type f -executable -delete
여기에서 삭제된 파일을 직접 찾을 수 있습니다(있는 경우). 추가 프로세스를 시작할 필요가 없기 때문에 더 효율적입니다. 쉘이나 xargs 프로세스에는 이스케이프 문자가 필요하지 않습니다. make
무엇을 해야 할지 알려주는 특수 문자는 없습니다 . "삭제할 파일이 없습니다" 상황을 올바르게 처리합니다.