프로그래밍 방식으로 OS X 명령줄 앱의 절대 경로 검색
프로그램은 를 수 ./proc/self/exe
을 구축해야 더 이 필요합니다 FreeBSD에서는 sysctl call을 구축해야 하기 때문에 더 많은 작업이 필요합니다.
int mib[4];
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
char buf[1024];
size_t cb = sizeof(buf);
sysctl(mib, 4, buf, &cb, NULL, 0);
하지만 아직 완전히 가능합니다 줄 에 대해 을 찾을 수 .그러나 명령 줄 응용 프로그램에 대해 OS X에서 이를 결정할 방법을 찾을 수 없습니다.다를 할 수 [[NSBundle mainBundle] bundlePath]
그러나 프로그램이 되지 않기 에 이 되지 않습니다
(: )argv[0]
왜냐하면, 만약 symlink에서 시작된다면,argv[0]
호출된 실행 파일로 가는 궁극적인 경로가 아니라 그 심볼링크가 될 것입니다.argv[0]
바보같은 애플리케이션이 사용한다면 또한 거짓말을 할 수 있습니다.exec()
호출하고 야생에서 본 argv를 제대로 초기화하는 것을 잊어버립니다.)
이 함수는 실행 파일(GUI 여부)에 대한 전체 경로를 반환합니다.경로에 기호 링크가 포함되어 있을 수 있습니다."..
", 그 외에도 필요하다면 그것들을 치울 수 있는 기능을 사용할 수 있습니다.자세한 내용은3
dyld
을 참조하십시오.
char path[1024];
uint32_t size = sizeof(path);
if (_NSGetExecutablePath(path, &size) == 0)
printf("executable path is %s\n", path);
else
printf("buffer too small; need size %u\n", size);
이 를 입니다 입니다.envp
프로세스를 생성할 때 배열합니다.rdyld
초기화 시 이를 잡고 포인터를 유지합니다.이 함수는 그 포인터를 사용합니다.
실제로 어떤 PID에도 적합하고 절대 경로를 직접 반환하는 훨씬 더 우아한 솔루션이 있다고 생각합니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libproc.h>
int main (int argc, char* argv[])
{
int ret;
pid_t pid;
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
pid = getpid();
ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf));
if ( ret <= 0 ) {
fprintf(stderr, "PID %d: proc_pidpath ();\n", pid);
fprintf(stderr, " %s\n", strerror(errno));
} else {
printf("proc %d: %s\n", pid, pathbuf);
}
return 0;
}
답은 당신이 할 수 없다는 것 같습니다.
저는 여러 가지 기능을 달성하고 실행 중인 프로세스에 대한 통계와 정보를 수집하려고 노력하고 있습니다.만약 제가 그렇게 느리지 않았다면 저는 기꺼이 그것을 고수할 것입니다.
를 다시 구현해 보면 작업이 많이 진행되기 때문에 속도가 느리다는 것을 알게 될 것입니다.
그것은 실제로는 사용자 모드이기 때문이 아니라 외부 호출기에서 지원하는 것을 찾기 위해 작업의 주소 공간을 검색해야 하기 때문인 것 같습니다.제가 커널에 있을 때 더 빠른 방법이 없을까요?
아닙니다. 저는 바보가 아닙니다. 해야 할 일을 하는 것입니다.해당 기능의 하위 집합을 원하는 경우에는 ls of source(사용 가능)부터 시작하여 요구 사항에 맞게 축소하는 것을 고려해 볼 수 있습니다.
호기심 때문에.
p_textvp
쓰임새가 있습니까?부모의 것으로 설정된 것 같습니다.p_textvp
인에kern_fork
(그러다가 풀려난 건가요?)?) 하지만 그 어떤 것도 손대지 않고 있습니다.kern_exec
의 일상적인 일들.
p_textvp
사용되지 않습니다.다윈에서 프로시저는 주소 공간의 루트가 아닙니다. 작업은 입니다.작업의 주소 공간을 매핑하여 처음에 채워야 하는 것은 아니기 때문에 작업의 주소 공간에 대한 "vnode" 개념은 없습니다.exec이 p_textvp를 채우면 모든 프로세스가 vnode에 의해 지원된다는 가정에 부합합니다.그러면 프로그래머는 vnode로의 경로를 얻을 수 있다고 가정하고, 여기서 vnode로의 현재 경로가 vnode가 시작된 경로이며, 문자열에 대한 텍스트 처리를 통해 애플리케이션 번들 이름이 생성될 수 있다고 가정합니다.이 모든 것들은 상당한 벌금 없이는 보장할 수 없을 것입니다.
—Mike Smith, Darwin Drivers 메일링 리스트
늦었지만.[[NSBundle mainBundle] executablePath]
는 bundled가 아닌 명령줄 프로그램에서도 잘 작동합니다.
내 생각에는 확실한 방법이 없습니다.argv[0]가 symlink이면 readlink()를 사용할 수 있습니다.$PATH를 통해 명령을 실행하면 검색(getenv("PATH")), getenv(_), dladdr() 중 일부를 시도할 수 있습니다.
단순하지 않은 이유realpath(argv[0], actualpath);
? 맞아요, 실제 경로는 (설명서 페이지에 나와 있는) 몇 가지 제한이 있지만 심볼릭 링크를 잘 처리합니다.FreeBSD 및 Linux에서 테스트 완료
% ls - l 푸바lrwxr-xr-x 1 bortzmeyer bortzmeyer 22 4월 2907:39 foobar -> /tmp/get-실명-exe % ./풋바내 진짜 경로: /tmp/get-real-name-exe
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <libgen.h>
#include <string.h>
#include <sys/stat.h>
int
main(argc, argv)
int argc;
char **argv;
{
char actualpath[PATH_MAX + 1];
if (argc > 1) {
fprintf(stderr, "Usage: %s\n", argv[0]);
exit(1);
}
realpath(argv[0], actualpath);
fprintf(stdout, "My real path: %s\n", actualpath);
exit(0);
}
PATH를 통해 프로그램이 시작되는 경우 픽셀비트의 솔루션을 참조하십시오.
GetProcessBundleLocation이 작동하는 것 같습니다.
언급URL : https://stackoverflow.com/questions/799679/programmatically-retrieving-the-absolute-path-of-an-os-x-command-line-app
'prosource' 카테고리의 다른 글
DB Connection 매개변수를 주전자에 전달 PDI 테이블 입력 단계를 Excel에서 동적으로 수행 (0) | 2023.09.20 |
---|---|
Vim에서 일치하는 XML 태그로 이동 (0) | 2023.09.20 |
파일 체크아웃 없이 Git 분기 전환 (0) | 2023.09.20 |
Uncatched ArgumentCountError: array_merge()가 알 수 없는 명명된 매개 변수를 허용하지 않습니다. (0) | 2023.09.20 |
SELECT를 위한 Mariaadb 반환 JSON (0) | 2023.09.20 |