bash/zsh에서 함수 및 모든 해당 쉘 관련 종속성을 추출하는 방법은 무엇입니까?

bash/zsh에서 함수 및 모든 해당 쉘 관련 종속성을 추출하는 방법은 무엇입니까?

나는 유용한 작은 기능을 많이 작성하고 때로는 친구나 세상과 공유하는 것을 좋아합니다. 문제는 내 함수에 도우미 함수와 별칭을 많이 사용하고 있는데 함수 코드를 한 줄씩 읽고 모든 종속성을 찾을 동기가 없다는 것입니다. 이 프로세스는 자동화될 수 있다고 확신합니다. 먼저 내보내려는 함수의 코드( which func코드를 가져오는 데 사용됨)에 태그를 지정한 다음 해당 태그에 대한 별칭을 내보내고 각 태그에 대해 이 프로세스를 반복적으로 반복해야 합니다( a를 수행 which token하고 그것이 존재하고 쉘과 관련되어 있는지 확인하십시오(따라서 바이너리에 대해 아무 작업도 수행하지 않거나 선택적으로 모든 바이너리를 binaries.txt에 추가한 다음 반복).

이 사용 사례에 대한 기존 도구가 있습니까?

그렇지 않은 경우 코드를 어떻게 표시합니까?

업데이트: 내가 제안한 접근 방식이 관련 없는 항목을 내보내고 모든 종속성을 내보낸다는 보장은 없지만 내 코드에서는 작동한다는 것을 알고 있습니다.

업데이트: 내 함수는 단순한 경향이 있으므로 내보내기 도구가 예제 인수를 사용하여 함수를 실행하고 이 특정 실행에 필요한 모든 종속성을 내보낸 경우에도 괜찮습니다.

답변1

쉘이 코드를 해석하는 방식은 대략적인 경험적 방법을 통해서만 대략적으로 추정할 수 있습니다. 예를 들어, 극단적인 경우에는 다음 사항을 알 수 없습니다.

foo() { "${0+b}$(echo AR | tr '[:upper:]' '[:lower:]')$1"; }
bar() { for i in 1 2; do foo "$i" "$i"; }

bar기능의지하다on foo이고 이를 실행하지 않고 작동합니다( bar1그리고 bar2모든 코드 경로를 통해 강제로 실행해야 합니다).

zshz실제로 쉘 토큰 연산자인 매개변수 확장 플래그( Q첫 번째 수준 참조를 제거하는 데에도 사용됨) 가 있습니다 . 그러나 그것은 당신이 원하는 것이 아닙니다.

예를 들어 에서는 를 반환 f() { foo "bar baz" "bar $(bar)"; }하고 함수 호출을 놓치게 됩니다 .${(z)functions[f]}foo"bar baz""bar $(bar)"bar

한 가지 접근 방식은 일반적인 함수 이름처럼 보이는 단어를 추출하는 것입니다( 에서 zsh함수 이름은 무엇이든 포함할 수 있지만 사람들은 [[:alnum:]:._-]문자 외에는 거의 사용하지 않음). 그런 다음 함수 이름 목록과 비교하여 확인합니다.

all_functions=(${(k)functions})
list-functions() (
  typeset -aU processed unprocessed=("$@") new list
  while (($#unprocessed)) {
    for f ($unprocessed) {
      autoload +X $f 2> /dev/null
      list=(${(s.:.)functions[$f]//[^[:alnum:]:._-]/:})
      new+=(${all_functions:*list})
      processed+=($f)
    }
    unprocessed=(${new:|processed})
  }
  print -rol -- $processed
)

_path_commands내가 얻은 완성 시스템의 기능을 테스트하는 방법은 다음과 같습니다.

_all_labels
_alternative
_arguments
c
_cache_invalid
_call_program
_call_whatis
_command_names
_complete
_completers
_dates
_delimiters
_describe
_description
_dispatch
_files
_globflags
_globqual_delims
_globquals
_groups
_have_glob_qual
_history_modifiers
_ignored
_jobs
_list_files
_main_complete
_message
_next_label
_next_tags
_nm
_normal
_object_files
_parameters
_path_commands
_path_commands_caching_policy
_path_files
_pick_variant
_requested
_retrieve_cache
_services
_set_command
_setup
_store_cache
_suffix_alias_files
_tags
u
_users
_wanted

( functions $(list-functions _path_commands)이러한 모든 함수의 정의를 덤프하려면 실행하세요).

거기에서 적어도 두 개의 거짓 긍정을 찾을 수 있습니다: cu, my 의 두 함수 ~/.zshrc. 변수 이름이나 매개변수 확장 플래그 또는 일부 명령 매개변수의 단어로 사용될 수도 c있지만 u이에 대해 우리가 할 수 있는 일은 없습니다.

나는 별칭에 대해 너무 걱정하지 않을 것입니다. 함수가 실행될 때 별칭은 확장되지 않습니다. 함수가 정의되거나 로드되면 확장되지만 후속 출력에는 functions확장된 형식이 표시됩니다.

관련 정보