[macOS] /usr/local/bin/svn: Argument list too long
Jenkins로 iOS빌드를 진행하던 중에 튀어나온 에러 메세지.
/var/folders/b9/nnx90k89w2_rw2gm0000gn/T/jenkins6214440116715.sh: line 2: /usr/local/bin/svn: Argument list too long
Jenkins의 Execute Shell Command를 통해 svn add를 실행하던 참이었다. 평소에도 문제없이 사용하고 있었는데, 갑자기 argument가 너무 길다니… 뭔가 잘못 됐나보다.
Command는 보통때와 다르지 않았다.
>svn add /path1/path2/path3/path4/Assetbundles/iOS/* --force
해당 폴더로 가서 ls를 실행해 보았다.
>cd /path1/path2/path3/path4/Assetbundles/iOS
>ls
아무 문제가 없었다. 하지만, 절대경로로 실행해 보니 역시 같은 에러가 났다.
>ls /path1/path2/path3/path4/Assetbundles/iOS/*
zsh: argument list too long: ls
command의 종류가 영향을 끼치지는 않는 것으로 보인다. svn이든 ls든 argument list가 OS가 허용하는 버퍼를 초과하는 모양새다. (사실 svn add가 문제인 줄 알고 한참을 헤맸다…)
그럼 argument가 허용하는 버퍼의 크기는 얼마인가. getconf로 알아보자.
>getconf ARG_MAX
262144
현재 OS 버전(Catalina 10.15.7) 기준으로 262144 byte가 argument limit으로 나온다. Big Sur에서는 1048576 byte라는 글이 있는데, 물론 확인은 해보지 않았다.
실제로 argument가 버퍼 사이즈를 넘는지 계산해 보았다.
/path1/path2/path3/path4/Assetbundles/iOS에 있는 파일 개수는 약 2500개 정도이므로, 262144 byte를 2500개로 나누면 파일 1개당 허용 평균 길이를 구할 수 있다.
262144 / 2500 = 104.8576
파일 경로 한개당 105 byte를 넘을 경우 argument 버퍼를 초과할 수 있다는 뜻이다. 절대 경로의 경우 파일의 경로와 파일 명으로 충분히 105 byte는 초과할 수 있는 것으로 보인다.
이제 원인은 알았으니, 해결은 어떻게 할 것인가. 경로를 줄이면 되겠는데, 아무래도 한 줄로는 쉽지 않을 것 같다. 해당 디렉토리로 이동한 후, svn이든 ls든 command를 실행하는 방법이 아무래도 제일 간단하다.
>cd /path1/path2/path3/path4/Assetbundles/iOS
>svn add ./* --force
경로를 떼어버리니 깔끔하게 잘 작동한다.
만약에, 파일이 너무 많거나 파일 명이 긴 것들이 많을 경우는 어찌할 것인가 생각해 봤는데, 아무래도 Regular Expression을 써서 argument의 개수를 줄이고 command를 여러 번 실행해야 할 것 같다.
svn add ./[A-Ma-m]* --force
svn add ./[N-Zn-z]* --force
svn add ./[0-9]* --force
이렇게 알파벳 기준으로 나누어 실행하면 문제는 없을 것 같다. (파일 명이 영문/숫자라고 가정)