foo
나는 일부 원래 함수를 재정의하고 실행 중에 해당 원래 함수(또는 그 복사본)를 호출하는 함수를 참조하기 위해 "오버라이드 래퍼"라는 표현을 사용합니다 .
이에 대한 Stack Exchange 스레드를 찾았습니다(예:이것), 하지만 제 경우에는 원본 파일 foo
과 덮어쓴 파일 모두를 foo
통해 액세스 FPATH
하고 자동 로드할 수 있어야 한다는 추가 요구 사항이 있습니다. (덮어쓴 버전이 검색 순서의 앞부분에 나타나 원본 버전을 가릴 수 있습니다.)
이를 수행할 수 있는 방법이 있습니까?
FWIW, 내가 작업 중인 특정 시나리오에서 재정의는 foo
원본에서 참조하는 일부 전역 변수에 일부 비표준 값을 할당하여 작업을 수행합니다.
답변1
autoload
이 함수를 사용하면 파일 이름이 함수 이름과 일치해야 한다는 제한 없이 this 와 동일한 방식으로 파일에서 함수 코드를 로드할 수 있습니다 .
## load_from FILE FUNCTION_NAME
load_from () {
eval "$2 () { $(<$1) }"
}
래퍼 코드는 아래와 같습니다. $^fpath/somefunction(N)
정의된 로드 경로 목록 으로 확장됩니다 (모든 항목에 대한 목록으로 확장되고 glob 한정자는 기존 파일로 확장을 제한합니다). 이는 단일 레이어 래퍼와 래퍼가 있는 경우에만 작동합니다.somefunction
$^fpath/somefunction
/dir/somefunction
/dir
$fpath
(N)
예f 경로에서.
#autoload somefunction
local some_parameter=overridden_value
local autoload_files
autoload_files=($^fpath/somefunction(N))
load_from $autoload_files[2] somefunction_wrapped
somefunction_wrapped "$@"
답변2
나는 데비안에서 바이너리/init.d 파일/스크립트를 래퍼로 대체하기 위해 수년간 프로덕션에서 파일 전송을 사용해 큰 성공을 거두었습니다.
숨기려는 원본 파일과 동일한 이름의 래퍼를 사용하는 경우 해당 패키지의 다음 업데이트에서 대체하려는 파일이 래퍼를 덮어쓸 가능성이 높습니다.
예를 들어 래퍼를 추가하려면 gcc
다음을 수행할 수 있습니다.
sudo dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc
그 후에 포장지를 씌우면 됩니다 /usr/bin/gcc
.
그 시점부터 이전 gcc
바이너리는 가 되며 /usr/bin/gcc.real
, 가장 중요한 것은 gcc
데비안 APT 시스템에서 수행/설치한 모든 후속 업데이트가 /usr/bin/gcc
as의 새 인스턴스를 설치 /usr/bin/gcc.real
하고 래퍼를 방해하지 않은 상태로 유지한다는 것입니다.
~에서man dpkg-divert
dpkg-divert는 전환 목록을 설정하고 업데이트하는 유틸리티입니다.
파일 전송은 dpkg(1)가 파일을 해당 위치가 아닌 전송된 위치에 설치하도록 강제하는 방법입니다. 파일이 충돌을 일으키면 데비안 패키지 스크립트를 통한 전송을 사용하여 제거할 수 있습니다. 시스템 관리자는 이를 사용하여 특정 패키지의 구성 파일을 무시하거나 이러한 파일이 포함된 최신 버전의 패키지를 설치할 때 dpkg에서 특정 파일("conffiles"로 표시되지 않음)을 보존해야 할 때마다 사용할 수 있습니다.
PS 저는 이 기술을 사용하여 추가 옵션을 추가 BIND
하고 스크립트를 초기화합니다.ISC-DHCP