execvp: /bin/bash: Ubuntu 20.04에서는 매개변수 목록이 너무 길지만 Ubuntu 18.04에서는 문제가 없습니다(모두 Windows 10 하위 시스템 사용).

execvp: /bin/bash: Ubuntu 20.04에서는 매개변수 목록이 너무 길지만 Ubuntu 18.04에서는 문제가 없습니다(모두 Windows 10 하위 시스템 사용).

새 Windows 10 PC를 구입하고 다음을 사용하여 (관리자로서) WSL 2를 설치했습니다.

wsl --install

그러면 WSL 2 및 Ubuntu 20.04 LTS가 설치됩니다. 그런 다음 WSL2 및 Ubuntu 18.04.6 LTS를 사용하여 동일한 Windows 10 pro 운영 체제를 사용하는 이전 PC에서 파일을 복사했습니다.

이제 동일한 폴더에서 똑같은 Makefile을 사용하면 오류가 발생합니다.

 make[1]: execvp: /bin/bash: Argument list too long
›cd /mnt/g/public_html/
›cd my_notes/
›cd solving_ODE/
›cd current_version
›cd OUTPUT/
›make -I$HOME all
make: execvp: /bin/bash: Argument list too long
make: *** [common.mk:761: all] Error 127

ARG_MAX검색해 보니 새 컴퓨터에서도 마찬가지인 것 같습니다 .

 >getconf ARG_MAX
 4611686018427387903

오래된 컴퓨터에서

 >getconf ARG_MAX
 2097152

두 컴퓨터 모두 동일한 운영 체제(Windows 10)를 실행하며 둘 다 64비트입니다.

ARG_MAX새 컴퓨터에서 수정해야 합니까? 위의 값은 새 컴퓨터에서는 이상하게 보입니다.

참고로 새 컴퓨터에서 Ubuntu는 다음과 같이 말합니다.

>xargs --show-limits
Your environment variables take up 2463 bytes
POSIX upper limit on argument length (this system): 4611686018427383392
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 4611686018427380929
Size of command buffer we are actually using: 131072
Maximum parallelism (--max-procs must be no greater): 2147483647

지금 실패하는 Makefile의 명령은 다음과 같습니다.

DIRS =  $(wildcard */.)

어디 도착해?폴더 목록현재 디렉토리에 있습니다. 나도 시도했다

DIRS = ${shell find . -type d -print}

같은 오류입니다.

8727이름이 매우 긴 폴더 가 있습니다 . 이전 컴퓨터의 폴더 수는 정확히 동일하며 아무것도 변경되지 않았습니다. Ubuntu 20.04의 쉘에서는 이것이 너무 큰 것 같습니다.

make새 PC의 버전은 GNU make 4.2.1이고, 기존 PC의 버전은 GNU make 4.1입니다. 새 PC의 Bash 버전은 GNU bash 5.0.16이고, 기존 PC의 Bash 버전은 4.4.20입니다.

이제 Windows 10 WSL2의 Ubuntu 20.04에서 동일한 Makefile이 실패하는 이유는 무엇입니까? ARG_MAX특정 구성 설정을 사용하여 값을 수정할 수 있습니까 ? 아니면 DIRS = $(wildcard */.)처음부터 이 문제를 피하기 위해 다른 것을 변경할 수 있는 방법이 있습니까 ?

참고로 아주 비슷한 질문이 있습니다makefile 매개변수 목록이 너무 길지만 특정 구성에만 해당됩니다. 저랑 설정이 완전 똑같네요. 그러나 여기서 질문은 동일한 메이크파일이 Ubuntu 18의 WSL2에서는 작동하지만 Ubuntu 20의 최신 WSL2에서는 작동하지 않는 이유는 무엇입니까? 모두 동일한 운영 체제(Windows 10 Pro)에서 실행됩니다.

이제 Windows 10에 Virtual Box를 설치하고 거기에 최신 Ubuntu를 설치하여 동일한 오류가 발생하는지 확인하겠습니다. 그렇지 않다면 Microsoft는 WSL용 Linux Ubuntu를 어떻게 구축해야 합니까?

고쳐 쓰다

해결 방법을 찾았습니다. 이 긴 매개변수 처리를 피하기 위해 Makefile을 다시 작성했습니다. 이제 처리할 디렉터리 이름의 긴 목록을 전달하는 대신(저는 재귀적 make를 사용합니다) 루프에서 하나씩 처리합니다. 이렇게 하면 작동합니다.

그러나 이상하게도 최신 WSL2 Ubuntu에서는 실패하지만 이전 WSL2 Ubuntu에서는 실패합니다. 저는 이 Makefile을 수년 동안 사용해 왔지만 한 번도 문제가 없었습니다.

이제 모든 준비가 완료되었습니다. 그러나 이는 Microsoft가 Ubuntu 20.04용 Linux 커널을 구축한 방식에 문제가 있을 수 있습니다. 나는 모른다. 그러나 ARG_MAX소스에서 Linux 자체를 다시 컴파일하는 것 외에는 이를 변경할 수 있는 방법이 없는 것 같습니다.

답변1

이는 make더 긴 인수를 처리하도록 패치되었습니다. 패치 파일 보기make-dfsg_4.1-9.1ubuntu1.diff.gz존재하다https://packages.ubuntu.com/en/source/bionic/make-dfsg:

+    if (unixy_shell && line_len > MAX_ARG_STRLEN)
+      {
+       unsigned j;
+       memcpy (ap, eval_line, sizeof (eval_line) - 1);
+       ap += sizeof (eval_line) - 1;
+       for (j = 1; j <= 2 * line_len / (MAX_ARG_STRLEN - 2); j++)
+         ap += sprintf (ap, "\\$\\{%u\\}", j);
+       *ap++ = '\\';
+       *ap++ = '"';
+       *ap++ = ' ';
+       /* Copy only the first word of SHELL to $0.  */
+       for (p = shell; *p != '\0'; ++p)
+         {
+           if (isspace ((unsigned char)*p))
+             break;
+           *ap++ = *p;
+         }
+       *ap++ = ' ';
+      }

Ubuntu 20에서는 makev4.2.1로 업그레이드한 후 이 패치를 더 이상 사용할 수 없습니다. 긴 인수를 방지하려면 Makefile을 최적화해야 합니다.

관련 정보