"매개변수 목록이 너무 깁니다"를 해결하는 데 있어 이 zsh의 역할은 무엇입니까?

"매개변수 목록이 너무 깁니다"를 해결하는 데 있어 이 zsh의 역할은 무엇입니까?

나는 읽었다이 답변@Gilles에서:

zsh에서는 mv내장 명령을 로드할 수 있습니다.

setopt extended_glob
zmodload -Fm zsh/files b:zf_\*
mv -- ^*.(jpg|png|bmp) targetdir/

문제에 대한 해결책으로 "mv: Argument list too long”. 대답은 zsh 사용을 제안합니다mv(GNU와 반대) 그런데 이 코드 줄은 정확히 무엇을 하는 걸까요? :

zmodload -Fm zsh/files b:zf_\*

답변1

zsh 문서를 보는 가장 좋은 방법은 info.

을 실행하면 info zsh다음을 사용할 수 있습니다.색인(생각해봐index)를 사용하여 명령을 설명하는 섹션을 찾습니다 zmodload.

을 눌러 i입력 zmo한 후 을 누르세요 Tab. zmodload모든 관련 정보를 알려주는 내장된 설명 으로 바로 이동하게 됩니다 .

즉, zmodload -F모듈을 로드하고(로드되지 않은 경우) 지정된 모듈만 활성화합니다.특징이 모듈에서.

여기에서는 패턴 일치 기능을 활성화했습니다 -m. 는 내장용이므로 위의 명령은 모듈을 로드하고(자세한 내용은 참고자료 참조) 로 시작하는 이름만 활성화합니다.mb:zf_*b:zsh/filesinfo -f zsh -n 'The zsh/files Module,'zf_

zmodload -F zsh/files

모듈을 로드하되 어떤 기능도 활성화하지 마세요.

$ zmodload -FlL zsh/files
zmodload -F zsh/files -b:chgrp -b:chown -b:ln -b:mkdir -b:mv -b:rm -b:rmdir -b:sync -b:zf_chgrp -b:zf_chown -b:zf_ln -b:zf_mkdir -b:zf_mv -b:zf_rm -b:zf_rmdir -b:zf_sync

현재 활성화된 기능을 지정하여 이 모듈의 기능을 나열합니다(현재는 없음). mvzf_mv내장이 있음을 알 수 있습니다 .

$ zmodload -mF zsh/files 'b:zf_*'
$ zmodload -FlL zsh/files
zmodload -F zsh/files -b:chgrp -b:chown -b:ln -b:mkdir -b:mv -b:rm -b:rmdir -b:sync +b:zf_chgrp +b:zf_chown +b:zf_ln +b:zf_mkdir +b:zf_mv +b:zf_rm +b:zf_rmdir +b:zf_sync

zf_mv내장 기능이 활성화되어 있지만 그 기능은 활성화되어 있지 않다는 것을 알 수 있습니다 mv(다른 내장 기능도 마찬가지입니다). 즉, 다음과 같은 내장 버전의 시스템 명령이 활성화되지만 시스템 명령을 재정의하지는 않습니다.

$ type zf_mv
zf_mv is a shell builtin
$ type mv
mv is /bin/mv

이제 내장된 mv,~처럼zf_mv, 아니요 mv, 다음과 같이 할 수 있습니다.

zf_mv -- ^*.(jpg|png|bmp) targetdir/

내장되어 있기 때문에 시스템 호출이 zf_mv없으므로 이와 관련된 제한에 execve()도달하지 않습니다 .Too many args

물론 다음과 같이 할 수도 있습니다.

zmodload zsh/files # without -F, all the features are enabled
mv -- ^*.(jpg|png|bmp) targetdir/

mv그러나 이는 시스템을 내장된 동등한 시스템으로 대체한다는 점에 유의하십시오 zsh.

오류를 극복하려면 E2BIG execve()(매개변수가 너무 많습니다.외부 명령 실행 시) zsh기능도 제공됩니다 zargs.

다음을 실행합니다.

autoload zargs # in ~/.zshrc if you use it often

자동 로딩으로 표시하세요.

그런 다음 다음을 사용할 수 있습니다.

zargs -- ^*.(jpg|png|bmp) -- mv -t targetdir/

(이것은 GNU를 옵션 mv으로 가정합니다). E2BIG를 피하기 위해 가능한 한 많은 명령을 실행합니다 .-tzargsmvxargs

답변2

bashism에 의존하지 않는 일반적인 솔루션이 있습니다: xargs.

xargs여기에서 매개변수 스트림을 읽고 stdin이를 지정된 유틸리티에 전달합니다. 귀하의 경우 명령줄은 다음과 같아야 합니다.

# find -E /source/dir -iregex ".*\.(jpg|png|bmp)" | xargz -n 1 -J % mv % /target/dir

이것이 의미하는 것은 현대적인 정규식(for|alternatives)을 사용한다는 것 -E입니다 . 이는 들어오는 스트림이 개별 매개변수로 분할된다는 것을 의미하며, 이는 각 매개변수가 다음에 문자가 나타날 때 대체된다는 것을 의미합니다.find-n 1-J %%

-J %xargs기본적으로 인수가 하위 명령 끝에 추가되기 때문에 필요합니다 . 그것이 부족하다는 것은 그것이 확실히 당신이 원하는 것이 아니라는 -J %것을 의미합니다 .xargs -n 1 -J % mv /target/dir %

관련 정보