오류: 매개변수 목록이 너무 깁니다.
sudo cp
그리고 find... -exec sudo cp
출력
/usr/bin/sudo(or find): Argument list too long
Travis CI 빌드 출력에서 이 오류가 발생합니다. 내 .travis.yml 파일은 쉘 스크립트(deploy.sh)를 사용하여 Branch2의 force-app 폴더에 대해 실행되고 git diff
출력(수천 개의 파일)은 cp
새 디렉터리에 있습니다.
sudo cp --parents $(git diff --name-only branch2 force-app/) $DEPLOYDIRECTORY;
오류는 두 줄입니다.
./deploy.sh: line 122: /usr/bin/git: Argument list too long
./deploy.sh: line 122: /usr/bin/sudo: Argument list too long
저도 나중에 똑같은 문제가 있었어요찾다주문하다. 나는 명명 규칙을 사용하여 git diff의 각 파일에 해당하는 파일을 찾아 복사합니다.
for FILE in $GIT_DIFF_FILES; do
if [[ $FILE == *Test.cls ]]; then
find $classPath -maxdepth1 -samefile "$FILE-meta.xml" -exec sudo cp --parents {} $DEPLOY_DIRECTORY +
fi;
done;
다시 오류가 발생합니다 ./deploy.sh: line 142: /usr/bin/find: Argument list too long
.
노트:Travis CI는 이 빌드를 위해 Ubuntu Linux(Xenial) 가상 환경을 실행하고 있습니다.
내가 시도한 것
1.스택 크기 재설정
Travis CI는 자동으로 스택 크기를 다음과 같이 설정합니다.8192인수 최대값은8388608새로운 빌드마다. 내 배포.sh 파일에서 ulimit -s 9999999
스택 크기를 다음으로 변경했습니다.9999999인수 최대값은2559999744새로운 빌드마다.
2. 명령 변경
sudo cp
내가 시도한 첫 번째 명령은 다음과 같습니다 .
- 포맷 명령은
for loop
tar -cf - -C files... | tar xpf - -C target directory...
- 포맷 명령은
git diff ... | xargs cp ...
find
내가 시도한 명령에 대해 :
find ... | xargs -n 1000 sudo cp ....
- 이 명령에 추가된 다른 플래그도 효과가 없습니다.
find ... -exec cp ...
- 플래그나 구문을 변경하면 동일한 오류가 반환됩니다.
명령을 변경하는 것은 해결책이 아닌 것 같습니다.
로컬에서 오류를 재현한 후 소수의 파일(~1000개 이하)과 상호 작용할 때 내 명령이 이미 제대로 작동하는 것을 발견했습니다.
그러나 출력이 cp
대략 다음과 같을 때find
git diff
1200~1500개 이상의 파일그런 다음 다음을 반환합니다.
매개변수 목록이 너무 깁니다.
또한, 또는 내 쉘 스크립트를 실행하면 다음 find
도 반환됩니다.cp
매개변수 목록이 너무 깁니다.
따라서 이 명령으로 무엇을 하는지는 중요하지 않은 것 같습니다. 보다 근본적인 원인은 문제의 원인이지만 출력되는 파일 개수가 git diff
약 1200개 파일을 초과하는 경우에만 해당됩니다.
cp
my 및 명령을 어떻게 수정합니까 find
?
오류를 재현하는 방법
내 사용 사례에 따라 이 오류를 재현하기 위해 수행해야 하는 단계는 다음과 같습니다. 저는 VS Code를 사용했기 때문에 최대한 저와 비슷하게 복제해 보시길 권해 드립니다. USERNAME
다음 코드를 사용자 이름으로 바꿔야 합니다 .
1단계: 포크이 창고.
2단계: 터미널에서 아래 코드의 각 줄을 한 번에 한 줄씩 실행합니다.
cd force-app/main/default
새 폴더 "diff"를 만듭니다. 그런 다음 아래에서 계속하십시오.
git checkout -b branch2
cd force-app/main/default/classes
//comment
하단에 추가myclass.cls그리고myclass.cls-meta.xml문서. 변경 사항을 저장하다.
for n in {001..1500}; do cp myclass.cls myclass$n.cls; done
for n in {001..1500}; do cp myclass.cls-meta.xml myclass$n.cls-meta.xml; done
git add .
git commit -m “first commit”
git push --set-upstream origin branch2
git checkout master
for n in {001..1500}; do cp myclass.cls myclass$n.cls; done
for n in {001..1500}; do cp myclass.cls-meta.xml myclass$n.cls-meta.xml; done
git add .
git commit -m “second commit”
git push
cd
sfdx-travisci 폴더로 돌아갑니다.
sudo cp -p $(git diff --name-only branch2 /Users/USERNAME/sfdx-travisci/force-app/main/default/classes) /Users/USERNAME/sfdx-travisci/force-app/main/default/diff
for file in $(sudo cp -p $(git diff --name-only branch2 /Users/USERNAME/sfdx-travisci/force-app/main/default/classes) /Users/USERNAME/sfdx-travisci/force-app/main/default/diff); do if [[ $file == *.cls ]]; then find /Users/USERNAME/sfdx-travisci/force-app/main/default/classes -samefile “$file-meta.xml” -exec sudo cp -p {} /Users/USERNAME/sfdx-travisci/force-app/main/default/diff +; fi; done;
답변1
복잡한 복사 명령 대체:
tar -cf - -C /home/auser/data . | tar xpf - -C /home/auser/data2
답변2
몇 가지 해결 방법을 시도하는 것보다 오류의 원인을 이해하는 것이 좋습니다. 해당 매개변수가 최대 매개변수 길이를 초과하여 오류가 발생합니다.앞으로명령을 호출하십시오.
이런 일이 발생할 수 있는 이유는
- 셸 확장으로 인해 너무 긴 매개변수 목록이 생성됨
- 너무 긴 인수 목록을 전달하는
find
가족 함수라는 프로세스(예: ).exec
이 명령은 getconf ARG_MAX
인수의 최대 길이를 알려줍니다.
주문하다
cp $(git diff --name-only branch2 force-app/) ...
git
명령을 실행한 다음 해당 출력을 인수로 전달하는 것을 의미합니다 cp
. 이 출력이 인수의 최대 길이를 초과하면 위의 오류가 발생합니다.
주문하다
find ... -exec cp -t target {} +
별로 다르지 않습니다. 명령 +
끝 에서 중괄호 대신 발견된 모든 파일의 이름을 전달하라고 find
지시하기 때문입니다.find
따라서 해결책은 거대한 매개변수 문자열을 생성하지 않는 명령을 공식화하는 방법을 찾는 것입니다. xargs
아니면 명령 대체가 당신의 친구일 수도 있습니다.
@AaronD.Marasco가 댓글에서 언급했듯이:
find ... -print0 | xargs -0 cp {} target
( xargs
최대 인수 길이를 담당합니다. 여기서 중괄호는 인수 xargs
가 아닌 인수 에 대한 것이지만 find
동일한 의미를 갖습니다.)
또는 프로세스 대체를 사용하십시오(이 경우 덜 효율적임).
while IFS= read -d $'\0' -r Filename; do
# do something with $Filename:
cp "$Filename" target
done < <(find ... -print0)
자세한 내용은 find
및 매뉴얼 페이지를 참조하십시오 xargs
.