macOS에서 install -Dm644가 usage 오류를 내거나 오류 없이 755로 설치될 때: -D가 맥에서 하는 일과 대체 방법을 직접 시험한 결과When install -Dm644 fails with a usage error on macOS, or installs with mode 755 without any error: what -D does on a Mac and the alternatives, tested directly
리눅스식 install -D 를 맥에서 돌려 usage 오류를 만났거나, 오류 없이 끝났는데 설치된 파일의 권한이 의도와 다른 독자가 원인을 가려내고 자기 상황에 맞는 대체 방법을 고르게 돕는다.
이 맥(26.6.2)의 install 은 -D 뒤에 오는 글자를 대상 폴더(destdir) 인자로 읽는다. 그래서 install -D -m 644 는 usage 오류와 64, install -Dm755 로 대상 폴더가 없으면 71로 멈추지만, 대상 폴더가 이미 있으면 install -Dm644 도 종료 코드 0으로 끝나며 파일 모드가 644 가 아니라 755 가 된다. 폴더를 먼저 만들고 install -m 으로 복사하면 GNU install -D 와 같은 결과를 얻고, umask 가 077 일 때 상위 폴더 권한이 갈리지 않게 하려면 umask 022 에서 폴더를 만든다.
Makefile 과 배포 스크립트에서 install -D 를 찾아 INSTALL 변수와 install -d, install -m 두 줄로 바꾸고, 설치 뒤 stat -f %Lp 로 모드를 한 번 읽어 의도한 값과 같은지 확인하라.
목차
한 줄 요약: 이 맥(26.6.2)의 install 은 -D 를 대상 폴더 인자로 읽어 -Dm644 가 모드를 755 로 만들므로, 폴더를 먼저 만들고 install -m 으로 나눠 쓴다.
리눅스 Makefile 에서 install -Dm755 tool $(DESTDIR)$(PREFIX)/bin/tool 처럼 폴더를 만들면서 파일을 설치하던 줄을 맥 터미널에서 돌리면 오류가 나거나, 오류 없이 끝나는데 권한이 의도와 다르다. 대상 폴더가 없으면 오류로 멈추고, 폴더가 이미 있으면 -Dm755 는 의도대로 설치되지만 -Dm644 처럼 755 가 아닌 모드를 붙인 형태는 오류 없이 755 로 설치된다. 띄어 쓴 -D -m 644 는 폴더가 있어도 usage 오류다. 이 글은 그 이유와, 맥에서 같은 결과를 내는 방법(다섯 가지와 ginstall)이 어디서 갈리는지를 이 맥에서 직접 돌려 보인다.
install: target directory `dest/tool' does not exist
usage: install [-bCcpSsUv] [-f flags] [-g group] [-m mode] [-o owner]
확인한 환경은 macOS 26.6.2 arm64 의 /usr/bin/install, 비교 기준으로 Homebrew 의 GNU coreutils 9.11 에 든 ginstall, 맥 기본 make 3.81, bash 3.2.57 이고 날짜는 2026-10-28 이다. 시험 스크립트는 LC_ALL=C 로 두 번씩 돌렸고 두 번째 결과는 첫 번째와 같았다. 다만 install 이 대상 폴더가 없을 때 내는 오류 문구의 INS@ 뒤 여섯 글자는 임시 파일 이름이라 실행마다 다르다. 같은 문제는 이미 공개돼 있다. GStreamer 프로젝트의 병합 요청 !49(2018)는 맥에서 깨지는 install -D 줄을 고치며 “install -D is not supported by BSD install” 이라고 적었다.
용어 몇 개. install 은 파일을 복사하면서 권한(모드)을 함께 정하는 명령이고, -D 는 GNU 설명서에 따르면 대상 파일의 빠진 상위 폴더를 만든 뒤 복사하는 옵션이다. GNU 는 많은 리눅스 배포판이 쓰는 명령 모음이고 맥의 명령은 BSD 계열이라 옵션이 다르다. 종료 코드는 명령이 끝나며 남기는 숫자로 0이 정상이다. 모드 644 는 소유자만 쓰고 다른 사람은 읽기만 하는 권한, 755 는 거기에 실행 권한을 더한 것이다. umask 는 새로 만드는 파일과 폴더에서 빼는 권한의 기본값이다.
맥의 install 이 거부하는 옵션과 받아 주는 옵션
옵션을 하나씩 바꿔 가며 tool 한 파일을 복사해 종료 코드를 쟀다. -m, -v, -C, -p, -b, -d 는 맥과 ginstall 모두 0이었다. 갈리는 쪽은 아래다.
| 옵션 | 맥 /usr/bin/install |
ginstall 9.11 |
|---|---|---|
-t 폴더 |
64 (illegal option -- t) |
0 |
--target-directory=폴더, --mode=644, --directory, --verbose |
64 (illegal option -- -) |
0 |
-T (install -T tool dest/x) |
64 (usage 만 나옴) | 0 |
-D (install -D tool dest/x) |
64 (usage 만 나옴) | 0 |
긴 옵션은 메시지가 illegal option -- - 로 나와 어떤 옵션이 문제인지 보이지 않는다. 눈에 띄는 쪽은 마지막 줄이다. -D 는 illegal option 이 아니라 usage 를 낸다. 맥에도 -D 가 있기 때문이다. 이 맥의 man install 은 -D destdir 를 “Specify the DESTDIR (top of the file hierarchy) that the items are installed in to” 로 설명하고 “This option does not affect where the actual files are installed” 라고 덧붙인다. 즉 맥의 -D 는 폴더를 만들어 주는 옵션이 아니라 뒤에 오는 단어를 대상 폴더 이름으로 먹는 옵션이고, 설치 위치에는 영향이 없다.
같은 줄이 맥에서 하는 일: 오류가 나거나, 모드가 755 가 된다
리눅스에서 쓰던 형태를 대상 폴더가 있을 때(dest 가 이미 있음) 그대로 돌렸다. 설치할 파일은 tool, 대상은 dest/tool 이다.
| 줄 | 맥 종료 코드 | 맥 결과 모드 | ginstall 결과 모드 |
|---|---|---|---|
install -Dm755 tool dest/tool |
0 | 755 | 755 |
install -Dm644 tool dest/tool |
0 | 755 | 644 |
install -D -m644 tool dest/tool |
0 | 755 | 644 |
install -D -m 644 tool dest/tool |
64 (target directory 'dest/tool' does not exist) |
파일 없음 | 644 |
install -m 644 tool dest/tool |
0 | 644 | 644 |
-Dm644 에서 -D 가 뒤따르는 m644 를 인자로 먹으니 -m 이 사라지고, 맥의 기본 모드 755(맥 man install 이 적은 기본값 rwxr-xr-x)가 그대로 적용된다. 종료 코드는 0이라 set -euo pipefail 스크립트도 “배포 끝”을 찍고 지나갔다. 설정 파일을 -Dm644 로 설치했다면 실행 권한이 붙은 설정 파일이 남는다. -D -m 644 처럼 띄어 쓰면 반대로 -m 이 -D 의 인자가 되고 644 가 파일 이름 자리로 밀려나 usage 오류가 난다.
대상 폴더가 없을 때(dest/bin 이 없음)는 이렇다.
| 줄 | 맥 종료 코드 | 맥 오류 | ginstall |
|---|---|---|---|
install -Dm755 tool dest/bin/tool |
71 | install: dest/bin/INS@……: No such file or directory |
0, dest/bin/tool 생성 |
install -D -m 755 tool dest/bin/tool |
64 | target directory 'dest/bin/tool' does not exist |
0, 생성 |
install -m 755 tool dest/bin/tool |
71 | 위와 같음 | 1, 폴더 없음 |
오류 화면이 지저분해 2>/dev/null 을 붙여도 종료 코드는 그대로 71과 64였고 dest 에는 항목이 하나도 없었다. 위험한 쪽은 폴더가 이미 있는 경우의 조용한 755 다. 맥 기본 make 3.81 에 리눅스식 Makefile(install -Dm755 tool …/bin/tool, install -Dm644 app.conf …/etc/app.conf)을 줬더니, 폴더가 없으면 make: *** [install] Error 71 에 make 가 2로 끝나 stage 가 비었다. 폴더를 미리 만들어 두면 make 가 0으로 끝났고 tool 은 755, app.conf 는 의도한 644 가 아니라 755 였다.
대신 쓸 수 있는 방법과 어디서 갈리는가
기준은 ginstall -D -m 644 tool dest/share/app/tool 의 결과다. 상위 폴더 share, share/app 이 없는 상태에서 이름·종류·권한·내용의 SHA-256 앞 12자를 항목마다 비교했다.
| 방법 | umask 022 | umask 077 | umask 002 |
|---|---|---|---|
함수 install_D(아래) |
같음 | 같음 | 같음 |
mkdir -p 뒤 install -m |
같음 | 폴더 700, 700 | 폴더 775, 775 |
install -d 상위폴더 뒤 install -m |
같음 | 폴더 700, 755 | 같음 |
mkdir -p 뒤 cp 와 chmod |
같음 | 폴더 700, 700 | 폴더 775, 775 |
mkdir -p 뒤 ditto 와 chmod |
같음 | 폴더 700, 700 | 폴더 775, 775 |
상위 폴더를 안 만들고 install -m |
71, 항목 없음 |
umask 022(이 맥의 기본)에서는 방법 다섯 가지가 기준과 같았다. 갈리는 자리는 umask 였다. GNU 설명서는 -d 가 만드는 상위 폴더에 “mode ‘u=rwx,go=rx’ (755), regardless of the -m option or the current umask” 를 준다고 적는다. -D 항목에는 모드 서술이 없지만, 시험에서 ginstall -D 도 umask 077 과 002 에서 상위 폴더가 755 였다. 반면 mkdir -p 는 umask 를 따라가서 077 에서는 700, 002 에서는 775 가 됐다. install -d 는 가운데 폴더만 umask 를 따르고 가장 안쪽 폴더는 755 였다(077 에서 700, 755). 함수는 폴더를 만드는 순간만 umask 022 로 바꿔 세 값 모두 기준과 같았다.
그대로 붙여 쓸 함수와 Makefile
모드를 먼저 받고 상위 폴더를 만든 뒤 install -m 으로 복사하는 함수다. 실패는 종료 코드로 올라온다.
install_D() { # 사용법: install_D 모드 원본 대상
[ $# -eq 3 ] || { echo "usage: install_D mode src dst" >&2; return 64; }
( umask 022; mkdir -p -- "$(dirname -- "$3")" ) && install -m "$1" -- "$2" "$3"
}
install_D 644 app.conf "$DESTDIR/etc/app.conf"
Makefile 은 install -D 한 줄을 INSTALL 변수와 폴더 만들기, 모드 설치 두 단계로 나눴다. 이 형태는 맥 install 과 ginstall 모두에서 tool 755, app.conf 644 로 끝났다.
INSTALL ?= install
install:
$(INSTALL) -d $(DESTDIR)$(PREFIX)/bin $(DESTDIR)$(PREFIX)/etc
$(INSTALL) -m 755 tool $(DESTDIR)$(PREFIX)/bin/tool
$(INSTALL) -m 644 app.conf $(DESTDIR)$(PREFIX)/etc/app.conf
Makefile 이 install 을 $(INSTALL) 변수로 부르고 있다면 리눅스식 줄을 그대로 두고 make INSTALL=ginstall 만 주는 길도 됐다(시험은 ginstall 의 절대 경로로 했고 tool 755, app.conf 644). ginstall 은 이 맥에서 Homebrew 의 coreutils 에 들어 있었다(설치 명령 자체는 시험하지 않았다). 어떤 install 인지 스크립트가 알아내려면 install --version 의 성공 여부를 쓴다. 맥은 illegal option -- - 와 64, ginstall 은 install (GNU coreutils) 9.11 과 0이었다.
시험한 함수의 동작은 이렇다.
- 원본 파일의 권한이 600 이어도
-m 644를 주면 결과는 644 였고, 모드를 생략하면 맥install과ginstall -D모두 755 였다. - 이미 있는 읽기 전용(444) 대상 위에도 함수와
ginstall이 모두 덮어써서 모드 755, 새 내용이 됐다. - 없는 원본은 함수가 71(
install: nosuch: No such file or directory),ginstall이 1이었고 둘 다 빈bin폴더는 만들어 둔 채였다. 상위 경로 한 칸이 일반 파일이면 함수가 1(mkdir … File exists),ginstall이 1이었다. - 대상에 공백이 든 이름은 둘 다 됐고, 폴더 없는 이름(
plain-name)도 둘 다 됐다. - 대상을 슬래시로 끝낸 폴더 형태(
dest/bin/)는ginstall도 1로 실패했고 함수도 71로 실패해 둘 다 파일이 생기지 않았다.
조용한 755 를 잡으려면 설치 뒤에 모드를 읽어 비교하는 한 줄이 필요하다. stat -f %Lp 파일 이 맥에서 모드 숫자(예: 644)를 돌려준다. 시험에서 install -Dm644 로 설치한 파일을 이 검사에 걸었더니 “모드 불일치: 기대 644, 실제 755” 가 나왔다.
시험하지 못한 것
리눅스에서 도는 GNU install 은 쓰지 못했고 이 맥의 ginstall 9.11 이 대신했다. 다른 macOS 버전(옛 버전에서는 -D 가 illegal option 일 수 있으나 확인하지 않았다), 소유자·그룹을 바꾸는 -o·-g, -s(strip), -M 메타로그, 여러 파일을 한 폴더에 설치하는 형태, 심볼릭 링크 대상, 확장 속성·ACL, 아주 많은 파일에서의 속도는 시험하지 않았다. make 는 맥 기본 3.81 한 가지만 썼고 GNU make 4 이상이나 CMake·autotools 가 만드는 install 규칙은 보지 않았다. 공개 기록은 증상을 확인하는 근거로만 썼고 검색량은 재지 않았다.
세 줄 요약
- 이 맥(26.6.2)의 install 은 -D 를 대상 폴더 인자로 먹어 -D -m 644 와 -t·–mode 같은 GNU 옵션을 64로 거부하고, 대상 폴더가 없으면 71로 멈추지만 -Dm644 는 폴더가 있으면 0으로 끝난다.
- -Dm644 로 설치한 파일의 모드는 644 가 아니라 맥 기본값 755 였으므로, 설정 파일에 실행 권한이 붙는데도 make 와 set -euo pipefail 스크립트가 성공으로 지나간다.
- 폴더를 먼저 만드는 install_D 함수나 INSTALL 변수 Makefile 은 ginstall -D 와 같은 결과를 냈고, umask 077 이나 002 에서도 같게 하려면 폴더를 umask 022 에서 만들며, 설치 뒤 stat -f %Lp 로 모드를 확인한다.
To help a reader who ran Linux-style install -D on macOS and hit a usage error, or whose command ended without error but left a file with permissions different from what was intended, find the cause and pick a replacement that fits their situation.
The install on this Mac (26.6.2) reads the text after -D as a destination-folder (destdir) argument. So install -D -m 644 fails with a usage error and 64, and install -Dm755 stops with 71 when the destination folder is missing, but when the folder already exists install -Dm644 also ends with exit code 0 and the file gets mode 755, not 644. Creating the folder first and copying with install -m gives the same result as GNU install -D, and to keep the parent-folder permissions the same when umask is 077, create the folders under umask 022.
Find install -D in your Makefiles and deploy scripts, replace it with an INSTALL variable plus separate install -d and install -m lines, and after installing read the mode once with stat -f %Lp to check that it matches what you intended.
Contents
One-line summary: The install on this Mac (26.6.2) reads -D as a destination-folder argument, so -Dm644 makes the mode 755; create the folder first and install with -m in a separate step.
If you run a line like install -Dm755 tool $(DESTDIR)$(PREFIX)/bin/tool, which created the folder while installing the file in a Linux Makefile, in a Mac terminal, it either fails, or ends without error but with permissions you did not intend. If the destination folder is missing it stops with an error. If the folder already exists, -Dm755 installs as intended, but a form with a mode other than 755 such as -Dm644 installs with mode 755 without any error, and the spaced form -D -m 644 is a usage error even when the folder exists. This article shows, by running things on this Mac, why that happens and where the ways of getting the same result on a Mac (five methods and ginstall) part ways.
install: target directory `dest/tool' does not exist
usage: install [-bCcpSsUv] [-f flags] [-g group] [-m mode] [-o owner]
The environment I checked is macOS 26.6.2 arm64 with /usr/bin/install, ginstall from Homebrew’s GNU coreutils 9.11 as the comparison baseline, the default make 3.81, and bash 3.2.57, on 2026-10-28. I ran the test scripts twice each with LC_ALL=C and the second result matched the first. The six characters after INS@ in the error message install prints when the destination folder is missing are a temporary file name, so they differ on every run. The same problem is already public. A GStreamer merge request, !49 (2018), fixed an install -D line that broke on a Mac and wrote “install -D is not supported by BSD install”.
A few terms. install is a command that copies a file and sets its permissions (mode) at the same time, and according to the GNU manual -D is an option that creates the missing parent folders of the destination file and then copies. GNU is the command collection many Linux distributions use, while the Mac’s commands are BSD-family, so the options differ. The exit code is the number a command leaves when it ends, and 0 means success. Mode 644 means only the owner can write and everyone else can only read, and 755 adds execute permission to that. umask is the default set of permissions removed from newly created files and folders.
Which options the Mac’s install rejects and which it accepts
I changed one option at a time, copied one file tool, and measured the exit code. -m, -v, -C, -p, -b and -d were 0 on both the Mac and ginstall. The differences are below.
| Option | Mac /usr/bin/install |
ginstall 9.11 |
|---|---|---|
-t folder |
64 (illegal option -- t) |
0 |
--target-directory=folder, --mode=644, --directory, --verbose |
64 (illegal option -- -) |
0 |
-T (install -T tool dest/x) |
64 (only usage shown) | 0 |
-D (install -D tool dest/x) |
64 (only usage shown) | 0 |
For long options the message reads illegal option -- -, so you cannot see which option is the problem. The last row is the one that stands out. -D gives a usage message, not illegal option, because the Mac has a -D too. This Mac’s man install describes -D destdir as “Specify the DESTDIR (top of the file hierarchy) that the items are installed in to” and adds “This option does not affect where the actual files are installed”. In other words, the Mac’s -D is not an option that creates folders for you; it is an option that swallows the next word as a destination-folder name and has no effect on where files are installed.
What the same line does on a Mac: it errors out, or the mode becomes 755
I ran the Linux-style forms as they are when the destination folder exists (dest already exists). The file to install is tool and the destination is dest/tool.
| Line | Mac exit code | Mac resulting mode | ginstall resulting mode |
|---|---|---|---|
install -Dm755 tool dest/tool |
0 | 755 | 755 |
install -Dm644 tool dest/tool |
0 | 755 | 644 |
install -D -m644 tool dest/tool |
0 | 755 | 644 |
install -D -m 644 tool dest/tool |
64 (target directory 'dest/tool' does not exist) |
no file | 644 |
install -m 644 tool dest/tool |
0 | 644 | 644 |
In -Dm644, -D swallows the following m644 as its argument, so -m disappears and the Mac’s default mode 755 (the default rwxr-xr-x that the Mac’s man install documents) is applied as it is. The exit code is 0, so a set -euo pipefail script also printed its “done” line and moved on. If you installed a config file with -Dm644, you are left with a config file that has execute permission. Written with a space, as -D -m 644, it goes the other way: -m becomes the argument of -D, 644 is pushed into the file-name position, and a usage error follows.
When the destination folder is missing (dest/bin does not exist) it goes like this.
| Line | Mac exit code | Mac error | ginstall |
|---|---|---|---|
install -Dm755 tool dest/bin/tool |
71 | install: dest/bin/INS@……: No such file or directory |
0, creates dest/bin/tool |
install -D -m 755 tool dest/bin/tool |
64 | target directory 'dest/bin/tool' does not exist |
0, creates it |
install -m 755 tool dest/bin/tool |
71 | same as above | 1, no folder |
Even when I appended 2>/dev/null because the error screen was messy, calling install directly still surfaced the exit codes 71 and 64, and dest had no entries at all. The dangerous side is the quiet 755 when the folder already exists. When I gave the Mac’s default make 3.81 a Linux-style Makefile (install -Dm755 tool …/bin/tool, install -Dm644 app.conf …/etc/app.conf), a missing folder gave make: *** [install] Error 71, make ended with 2, and stage stayed empty. When I created the folders in advance, make ended with 0, tool was 755, and app.conf was 755, not the intended 644.
Alternatives and where they diverge
The baseline is the result of ginstall -D -m 644 tool dest/share/app/tool. With the parent folders share and share/app absent, I compared each item by name, type, permissions, and the first 12 characters of the SHA-256 of the content.
| Method | umask 022 | umask 077 | umask 002 |
|---|---|---|---|
Function install_D (below) |
same | same | same |
mkdir -p then install -m |
same | folders 700, 700 | folders 775, 775 |
install -d parent-folder then install -m |
same | folders 700, 755 | same |
mkdir -p then cp and chmod |
same | folders 700, 700 | folders 775, 775 |
mkdir -p then ditto and chmod |
same | folders 700, 700 | folders 775, 775 |
install -m alone without creating the parent folder |
71, no entries |
Under umask 022 (this Mac’s default) five methods matched the baseline. Where they diverged was umask. The GNU manual says the parent folders that -d creates get “mode ‘u=rwx,go=rx’ (755), regardless of the -m option or the current umask”. The -D entry has no mode statement, but in the test ginstall -D also made the parent folders 755 under umask 077 and 002. mkdir -p, on the other hand, follows umask: 700 under 077 and 775 under 002. With install -d only the middle folder followed umask and the innermost folder was 755 (700, 755 under 077). The function switches to umask 022 only at the moment it creates the folders, and all three values matched the baseline.
A function and a Makefile you can paste as they are
This is a function that takes the mode first, creates the parent folders, and then copies with install -m. Failures come up as exit codes.
install_D() { # usage: install_D mode src dst
[ $# -eq 3 ] || { echo "usage: install_D mode src dst" >&2; return 64; }
( umask 022; mkdir -p -- "$(dirname -- "$3")" ) && install -m "$1" -- "$2" "$3"
}
install_D 644 app.conf "$DESTDIR/etc/app.conf"
For the Makefile, I split the install -D line into two steps, creating folders and installing with a mode, using an INSTALL variable. This form ended with tool 755 and app.conf 644 on both the Mac’s install and ginstall.
INSTALL ?= install
install:
$(INSTALL) -d $(DESTDIR)$(PREFIX)/bin $(DESTDIR)$(PREFIX)/etc
$(INSTALL) -m 755 tool $(DESTDIR)$(PREFIX)/bin/tool
$(INSTALL) -m 644 app.conf $(DESTDIR)$(PREFIX)/etc/app.conf
If the Makefile calls install through an $(INSTALL) variable, leaving the Linux-style lines as they are and just passing make INSTALL=ginstall also worked (I tested with the absolute path of ginstall; tool 755, app.conf 644). ginstall was part of Homebrew’s coreutils on this Mac (I did not test the installation command itself). For a script to find out which install it has, use whether install --version succeeds. On the Mac it was illegal option -- - and 64, and ginstall printed install (GNU coreutils) 9.11 and 0.
The behavior of the function I tested was as follows.
- Even if the source file’s permission was 600, giving
-m 644produced 644, and when the mode was omitted both the Mac’sinstallandginstall -Dgave 755. - Over an existing read-only (444) destination, both the function and
ginstalloverwrote it, giving mode 755 and the new content. - For a missing source, the function gave 71 (
install: nosuch: No such file or directory) andginstallgave 1, and both left an emptybinfolder behind. When one step of the parent path was a regular file, the function gave 1 (mkdir … File exists) andginstallgave 1, and with 2 arguments the function gave 64. - A destination name containing a space worked on both, and so did a name with no folder part (
plain-name). - A destination written as a folder ending in a slash (
dest/bin/) failed with 1 onginstalland with 71 in the function, so no file was created on either.
To catch the quiet 755 you need one line that reads the mode after installing and compares it. stat -f %Lp file returns the mode number (for example 644) on a Mac. When I ran a file installed with install -Dm644 through this check, it printed a mismatch message saying expected 644, got 755.
What I could not test
I could not use the GNU install that runs on Linux, and this Mac’s ginstall 9.11 stood in for it. I did not test other macOS versions (on older versions -D might be illegal option, but I did not check), -o and -g that change owner and group, -s (strip), the -M metalog, forms that install several files into one folder, symbolic-link destinations, extended attributes and ACLs, or speed with very many files. For make I used only the Mac’s default 3.81, and I did not look at GNU make 4 or later, or the install rules that CMake and autotools generate. I used the public record only as evidence of the symptom and did not measure search volume.
Three-line summary
- The install on this Mac (26.6.2) swallows -D as a destination-folder argument, so it rejects -D -m 644 and GNU options such as -t and –mode with 64 and stops with 71 when the folder is missing, but -Dm644 ends with 0 when the folder exists.
- A file installed with -Dm644 got the Mac’s default mode 755, not 644, so a config file gains execute permission while make and set -euo pipefail scripts pass as successes.
- The install_D function that creates the folder first and a Makefile with an INSTALL variable gave the same result as ginstall -D, create folders under umask 022 to match under umask 077 or 002, and check the mode with stat -f %Lp after installing.