ZSH의 모든 명령에 대해 "매개변수 목록이 너무 깁니다"

ZSH의 모든 명령에 대해 "매개변수 목록이 너무 깁니다"

설명이 좀 더 자세했으면 좋았을 텐데, 한동안 같은 Artix 설정을 사용하고 있는데 스스로 고칠 수 없는 문제는 없습니다. 그러나 VirtualBox를 설치한 후(이 문제와 관련이 없다고 생각함) 재부팅 후 갑자기 터미널에서 어떤 명령도 실행할 수 없습니다. 매개변수 개수나 매개변수 개수에 관계없이 zsh는 매개변수 목록이 너무 길다고 응답합니다. 이는 dwm 실행부터 ls 사용까지 모든 작업에서 발생합니다. .zshrc를 최소한으로 스크러빙해 보았지만 무엇을 시도해도 작동하지 않습니다. 그러나 Bash와 Shell은 작동합니다. 어떤 아이디어가 있나요?

답변1

매개변수 목록이 너무 깁니다.일반적으로 E2BIG 오류 코드에 해당하는 오류 메시지는 다음과 같습니다.

$ zmodload zsh/system
$ syserror E2BIG
Argument list too long

execve()E2BIG는 인수 목록 및 환경 변수 문자열의 실행이 필요한 명령이 지원되는 명령보다 크거나 Linux에서 단일 인수 또는 환경 문자열이 128KiB보다 큰 경우 반환되는 오류 코드입니다.

전반적인 제한 사항 및 방법크기계산은 시스템에 따라 다릅니다. 최신 버전의 Linux에서는 현재 스택 크기 제한으로 인해 발생합니다. 다음과 같이 얻을 수 있습니다 getconf ARG_MAX(할 수 있다고 가정 getconf).

$ getconf ARG_MAX
2097152
$ limit stacksize 1024 # KiB, so 1MiB
$ getconf ARG_MAX
262144

이는 최소 128KiB이지만 스택 크기 제한의 1/4입니다(스택 크기 제한을 너무 낮게 낮추면 모든 종류의 다른 문제가 발생하기 시작합니다).

여기서는 인수 목록이 작은 명령을 포함하여 모든 명령에 대해 오류가 발생하므로 환경 변수가 매우 크거나 환경 변수 및 해당 누적 크기가 값에 전달되어 한계에 도달했다고 합리적으로 가정할 수 있습니다.처형된명령이 ARG_MAX보다 큽니다.

예를 들어, POSIX 옵션을 잘못 설정하여 모든 셸 변수가 환경에 배치되고 많은 변수가 정의된 경우 (아마도 일부는 다른 완료 기능을 실행하여) allexport이런 일이 발생할 수 있습니다.은닉처변수의 정보.

조사하다:

echo $options[allexport]

보고되어야 합니다 off. 그렇지 않은 경우 이 옵션을 설정하는 시작 파일을 확인하십시오. set -a, set -o allexport, setopt allexport, options[allexport]=on또는 옵션의 다양한 철자가 될 수 있습니다 (대소문자와 밑줄은 무시되므로 setopt ALL_EXPORT예를 들어 될 수도 있음).

시도해 볼 수 있는 다른 작업은 다음과 같습니다.

현재 스택 크기 제한을 확인하세요.

$ limit stacksize
stacksize       8MB

ARG_MAX의 현재 값을 확인합니다.

$ (typeset +x -m '*'; getconf ARG_MAX)
2097152

typeset +x -m '*'모든 환경 변수를 삭제합니다. 이는 포함되어 있지만 시스템에서는 기본적으로 이를 찾을 $PATH수 있습니다 .getconf$PATH

환경 크기를 확인합니다.

$ typeset -x | wc -c
4395

(이것은 근사치이며 쉘 변수에 매핑되지 않은 변수를 포함하지 않습니다. 개수에는 typeset -x변수 값에 없는 일부 추가된 따옴표 문자가 포함될 수 있으며 목록도 계산해야 한다는 점을 고려하지 않습니다. 이러한 환경 문자열에 대한 포인터는 크기입니다.

128KiB보다 큰 환경 변수를 찾습니다.

$ LC_ALL=C
$ export test=${(l[132000])}
$ for v (${(k)parameters[(R)*export*]}) {(( (l=${(P)#v}) >= 131071 )) && echo "$v: $l"}
test: 132000
$ ls
ls:2: argument list too long: ls

root이 문제의 영향을 받지 않는 별도의 실행 셸에서 다음을 실행할 수도 있습니다.

strace -s150000 -vfe execve -p "$pid"

$pid문제의 셸의 프로세스 ID는 어디에 있으며( 출력 참조 echo $$) 해당 셸에서 명령을 실행해 보세요.

straceexecve()그러면 실행되고 실패한 정확한 시스템 호출 과 인수 및 환경 문자열(각각 150000바이트로 잘림)의 전체 목록이 표시되므로 E2BIG문제를 식별하는 데 도움이 될 것입니다.

관련 정보