C에서 실행 파일의 위치를 어떻게 찾습니까? [복제]
이 질문에는 이미 답변이 있습니다.
C / C ++에서 현재 실행중인 프로그램의 위치 (전체 경로)를 찾는 방법이 있습니까?
(문제 argv[0]
는 전체 경로를 제공하지 않는다는 것입니다.)
요약:
/proc
정말 똑 바르고 실현 가능한 방법으로 유닉스 에서 :readlink("/proc/self/exe", buf, bufsize)
(리눅스)readlink("/proc/curproc/file", buf, bufsize)
(FreeBSD)readlink("/proc/self/path/a.out", buf, bufsize)
(솔라리스)
유닉스가없는
/proc
경우 (위에서 실패한 경우) :argv [0]이 "/"(절대 경로)로 시작하면 이것이 경로입니다.
그렇지 않으면 argv [0]에 "/"(상대 경로)가 포함되어 있으면 cwd에 추가하십시오 (아직 변경되지 않은 경우).
그렇지 않으면 디렉토리에서
$PATH
실행 파일을 검색하십시오argv[0]
.
나중에 실행 파일이 실제로 심볼릭 링크가 아닌지 확인하는 것이 합리적 일 수 있습니다. 그것이 symlink 디렉토리와 관련하여 해결되면.
이 단계는 / proc 메소드에서 필요하지 않습니다 (적어도 Linux의 경우). proc symlink는 실행 파일을 직접 가리 킵니다.
argv[0]
올바르게 설정하는 것은 호출 프로세스에 달려 있습니다. 대부분의 경우가 맞지만 호출 프로세스를 신뢰할 수없는 경우가 있습니다 (예 : setuid 실행 파일).Windows : 사용
GetModuleFileName(NULL, buf, bufsize)
사용 하여 GetModuleFileName () Windows를 사용하는 경우 기능을.
다음 주석은 유닉스 전용입니다.
이 질문 에 대한 답은 모든 경우에이 질문에 올바르게 대답 할 수있는 일반적인 방법 이 없다는 것입니다. 아시다시피, argv [0]은 부모 프로세스에 의해 전혀 설정 될 수 없으므로 프로그램의 실제 이름이나 파일 시스템에서의 위치와는 관계가 없습니다.
그러나 다음과 같은 휴리스틱이 종종 작동합니다.
- argv [0]이 절대 경로 인 경우 이것이 실행 파일의 전체 경로라고 가정하십시오.
- argv [0]이 상대 경로 인 경우 (즉, a 포함
/
) getcwd ()를 사용하여 현재 작업 디렉토리를 판별 한 후 argv [0]을 추가하십시오. - argv [0]이 일반 단어 인 경우 $ PATH를 검색하여 argv [0]을 찾은 다음 argv [0]을 찾은 디렉토리에 추가하십시오.
이들 모두는 해당 프로그램을 호출 한 프로세스에 의해 우회 될 수 있습니다. 마지막으로 emg-2에서 언급 한 것과 같은 Linux 관련 기술을 사용할 수 있습니다. 다른 운영 체제에는 동등한 기술이있을 수 있습니다.
위의 단계가 유효한 경로 이름을 제공한다고 가정하더라도 실제로 원하는 경로 이름이 없을 수도 있습니다 (실제로 원하는 것은 구성 파일을 찾을 수 있다고 생각하기 때문에). 하드 링크가 있으면 다음과 같은 상황이 발생할 수 있습니다.
-- assume /app/bin/foo is the actual program
$ mkdir /some/where/else
$ ln /app/bin/foo /some/where/else/foo # create a hard link to foo
$ /some/where/else/foo
이제 위의 접근 방식 (/ proc / $ pid / exe 포함)이 /some/where/else/foo
프로그램의 실제 경로를 제공합니다. 사실, 그것은 당신이 원하는 것이 아니라 프로그램 의 실제 경로입니다. 이 문제는 실제로 하드 링크보다 훨씬 일반적인 기호 링크에서는 발생하지 않습니다.
이 접근 방식이 원칙적으로 신뢰할 수 없다는 사실에도 불구하고 실제로는 대부분의 목적에 적합합니다.
실제로는 대답이 아니라 명심해야 할 사항입니다.
보시다시피, 실행 파일 실행 위치를 찾는 문제는 Linux 및 Unix에서 매우 까다 롭고 플랫폼별로 다릅니다. 그렇게하기 전에 두 번 생각해야합니다.
당신은 몇 가지 구성 또는 리소스 파일을 발견하기위한 실행 파일의 위치를해야 할 경우, 아마도 당신이 시스템에 파일을 배치하는 유닉스 방식 따라야 넣어 CONFIGS를로 /etc
하거나 /usr/local/etc
또는 현재 사용자 홈 디렉토리, 그리고 /usr/share
자원 파일을 넣을 수있는 좋은 장소입니다.
많은 POSIX 시스템에서 / proc / PID / exe 아래에있는 simlink를 확인할 수 있습니다. 몇 가지 예 :
# file /proc/*/exe
/proc/1001/exe: symbolic link to /usr/bin/distccd
/proc/1023/exe: symbolic link to /usr/sbin/sendmail.sendmail
/proc/1043/exe: symbolic link to /usr/sbin/crond
유닉스 시스템에서 바이너리는 시작된 이후에 제거되었을 수도 있습니다. 유닉스에서는 완벽하게 합법적이고 안전합니다. 마지막으로 확인한 Windows에서 실행중인 바이너리를 제거 할 수 없습니다.
/ proc / self / exe는 여전히 읽을 수 있지만 실제로 작동하는 심볼릭 링크는 아닙니다. 이상 할 것입니다.
Linux의 경우 /proc/self/exe
binreloc이라는 멋진 라이브러리에 묶여있는 작업을 수행 하는 방법을 찾을 수 있습니다.
Mac OS X에서는을 사용하십시오 _NSGetExecutablePath
.
참조 man 3 dyld
및 이 대답 비슷한 질문에.
나는
1) basename () 함수를 사용하십시오 : http://linux.die.net/man/3/basename
2) chdir () 해당 디렉토리
3) getpwd ()를 사용하여 현재 디렉토리를 가져 오십시오.
이렇게하면 ./ 또는 ../bin/ 대신 깔끔하고 완전한 형태로 디렉토리를 얻을 수 있습니다.
프로그램에 중요한 경우 현재 디렉토리를 저장하고 복원하고 싶을 수도 있습니다.
참고 URL : https://stackoverflow.com/questions/933850/how-do-i-find-the-location-of-the- executable-in-c
'Programming' 카테고리의 다른 글
Parallel.ForEach () 대 foreach (IEnumerable) (0) | 2020.06.20 |
---|---|
ld (linker) 검색 경로를 인쇄하는 방법 (0) | 2020.06.20 |
Golang에서 문자열을 분할하여 변수에 할당하는 방법은 무엇입니까? (0) | 2020.06.20 |
Mockito에서 Varargs를 올바르게 일치시키는 방법 (0) | 2020.06.20 |
Java의 toString과 동등한 C ++? (0) | 2020.06.20 |