Makefile이 포함된 디렉터리가 여러 개 있습니다.
Makefile이 존재하는 경우 이를 실행하기 위해 이 스크립트를 만들었습니다.
find . -name "Makefile" -exec sh -c 'make re -C "$1" $(dirname "$0")' {} \;
하지만 작동하지 않는 것 같습니다. 다음 오류가 발생합니다.
make: the `-C' option requires a non-empty string argument
Usage: make [options] [target] ...
Options:
-b, -m Ignored for compatibility.
-B, --always-make Unconditionally make all targets.
-C DIRECTORY, --directory=DIRECTORY
[...]
하지만 or make re -C
로 교체하면 잘 작동합니다 ...echo
printf
find . -name "Makefile" -exec sh -c 'printf "%s\n" "$1" $(dirname "$0")' {} \;
# or
find . -name "Makefile" -exec sh -c 'echo "$1" $(dirname "$0")' {} \;
답변1
원래 코드는 두 개의 매개변수 $0
및 를 사용 $1
하지만 에 무언가를 전달하기만 하고 $0
비워 둡니다 $1
. 이로 인해 make
행동 방식에 대해 불평하게 될 수 있습니다.
너할 수 있다원하는 경우 "$1"
피연산자와 옵션의 순서가 혼합되어도 상관없다고 가정하고 명령에서 간단히 제거하고 명령 대체를 인용하여 이 문제를 해결할 수 있지만 다음과 같은 몇 가지 다른 아이디어를 제공하겠습니다. 잘.dirname
make
다음 두 명령은 Makefile
현재 디렉터리 또는 그 아래에서 호출되는 모든 일반 파일을 찾은 다음 make -C
해당 파일이 있는 각 디렉터리에 대상을 만드는 데 사용됩니다.re
find . -name Makefile -type f -exec sh -c 'make -C "${1%/*}" re' sh {} \;
또는
find . -name Makefile -type f -exec sh -c '
for pathname do
make -C "${pathname%/*}" re
done' sh {} +
두 번째 명령에서는 sh -c
단일 이름 대신 찾은 경로 이름을 최대한 많이 반복하도록 스크립트를 변경했습니다.
나는 dirname
두 명령을 모두 의 표준 인수 확장으로 대체했습니다 $pathname
.하나파일이 현재 디렉터리에 있더라도 Makefile
경로 이름에는 슬래시가 포함되어 있으므로 안전합니다.아니요dirname
더 빠른 대안 으로 변경하고 싶습니다 .
해당 옵션과 함께 작동 하지 않는 make
더 빠른 변형은 -C
다음의 (비표준) 조건자를 사용하여 실행하는 것입니다.make
-execdir
find
find . -name Makefile -type f -execdir make re \;
그러면 find
작업 디렉터리가 make
파일이 있는 디렉터리로 변경됩니다. Makefile
이 변형의 장점은 스크립트를 make
처리하지 않고 직접 실행된다는 것입니다.sh -c
답변2
그것을 사용하는 것보다 make -C
그냥 디렉토리로 들어가는 것이 더 쉽습니다.cd
이 구현은 잘 작동합니다.
find . -name "Makefile" -exec sh -c 'cd "$(dirname "$0")" && make re' {} \;