Bash 매개변수 확장 - 하이픈을 이스케이프 처리하면서 접두사가 있는 변수 가져오기

Bash 매개변수 확장 - 하이픈을 이스케이프 처리하면서 접두사가 있는 변수 가져오기

편집하다: 나는 이 게시물의 핵심 가정을 오해했다는 것을 깨달았습니다. 구문은 ${!prefix@}함수 이름을 얻을 수 없고 변수만 얻을 수 있습니다. 따라서 ${!prefix@}밑줄이 있어도 함수 이름을 반환할 수 없습니다.그러므로 아래의 굵은 질문에 대한 나의 대답은 단호하게 "아니요"입니다. 그럼에도 불구하고 아래 Edgar의 답변은 특정 접두사를 기반으로 함수 이름 목록을 얻으려는 사람들에게 도움이 될 것입니다.

원래 질문

이것Bash 매개변수 확장 매뉴얼현재 환경에서 특정 접두사로 시작하는 모든 변수(비함수) 목록을 얻는 방법을 제공합니다.

${!prefix@}

foo-예를 들어 foo-setup, 등 으로 시작하는 여러 함수가 있습니다 foo-run. foo-initialize이제 시도했지만 . ${!foo-@}로 시작하는 함수 목록을 반환하는 변형을 얻지 못했습니다 foo-. 나는 ${!foo\-@}, , , , 및 기타 다양한 변형을 시도했습니다 "${!foo\-@}". 매개변수 확장에서 하이픈이 고유한 의미를 갖고 있다는 것을 알고 있으므로 일부 이스케이프나 유사 없이는 작동하지 않을 것으로 예상됩니다. 그러나 나는 또한 Bash가 인수 확장 중을 포함하여 어떤 상황에서든 특수 문자를 이스케이프 처리할 수 있는 메커니즘을 가져야 한다고 기대합니다. 단, 여기서는 그렇지 않을 수도 있습니다."${!foo-@}"bar=foo; ${!${bar}-@}-

(나는 크로스 플랫폼 호환성을 원한다면,하이픈으로 연결된 함수 이름을 피하세요.. 나는 이것에 동의합니다. 또한 밑줄 대신 하이픈을 사용하여 함수를 입력하는 것이 훨씬 더 부드럽습니다...)

그래서 나는 탐구 정신으로 이런 질문을 던진다.하이픈 접두어로 시작하는 모든 정의된 함수(또는 일반적으로 이름 참조) 목록을 가져오기 위해 기본 매개변수 확장을 사용할 수 있는 방법이 있습니까?어쩌면 해결책은 내가 모르는 방식으로 하이픈을 피하는 것일 수도 있습니다.

(그렇지 않다면 전체 변수 목록을 가져온 다음 필수 하이픈 접두사가 있는 변수만 남기도록 필터링하는 대안이 있습니까?)

답변1

대안이 있나요?

declare예, 또는 compgen정의된 함수 목록을 얻으려면 다음을 사용할 수 있습니다 .

해결 방법 1(지정된 문자열/패턴을 포함하는 함수와 일치함)

declare -F | grep -o 'foo-.*'
#or
compgen -A function | grep 'foo-'

해결 방법 2(구체적으로 접두사 일치/특정 문자열/패턴으로 시작)

declare -F | cut -d ' ' -f3 | grep '^foo-'
#or
compgen -A function | grep '^foo-'

매개변수 확장 사용과 관련하여 함수 이름을 얻는 것이 가능한지 잘 모르겠습니다. 매뉴얼에 따르면 변수에서만 작동하는 것 같습니다.

${!접두사*}

${!접두사@}

IFS 특수 변수의 첫 번째 문자로 구분된 이름이 접두사로 시작하는 변수 이름으로 확장됩니다. "@"를 사용하고 큰따옴표 안에 확장이 발생하면 각 변수 이름이 별도의 단어로 확장됩니다.

그리고 당신이 말한 것 :

물론, 모든 함수의 이름을 바꾸고 foo- 접두사를 foo_로 변경하면 ${!foo_@}가 모든 함수를 가져옵니다.

이것을 시도해 보시고 효과가 있었는지 궁금합니다. (제 생각에는 아닌 것 같습니다.) 몇 가지 기능으로 테스트했는데 작동하지 않았기 때문입니다.

물론 하이픈을 사용하여 변수를 정의할 수는 없으므로 or 를 -사용하는 것은 불가능합니다 .${prefix-@}${prefix-*}

답변2

완전성을 위해 zsh의 패턴과 일치하는 함수 이름 목록을 얻으려면 다음을 수행할 수 있습니다.

typeset +f -m 'foo-*'

( 이러한 함수의 정의도 확인하여 +f대체 하세요)-f

그러나 zsh의 함수 이름은 임의의 바이트 시퀀스일 수 있습니다(결국 명령과 동일한 네임스페이스에 있고 파일 경로는 null이 아닌 바이트의 null이 아닌 시퀀스일 수 있음). 따라서 출력은 다음과 같습니다. 안정적으로 사후 처리되지 않았습니다.

그러나 패턴을 캡처하는 k특별한 연관 배열 눈을 보면 $functions배열의 목록을 얻을 수 있습니다.M

foo_functions=( ${(Mk)functions:#foo-*} )

이상한 이름을 가진 함수의 예:

$ typeset +f -m 'foo-*'
foo-a
b
c
foo-barbaz
$ print -rC1 -- ${(q)foo_functions}
foo-a$'\n'b$'\n'c
foo-bar$'\0'baz

관련 정보