IT이야기

C에서 실행 파일의 위치를 찾으려면 어떻게 해야 하는가?

cyworld 2022. 5. 25. 22:21
반응형

C에서 실행 파일의 위치를 찾으려면 어떻게 해야 하는가?

C/C++에서 현재 실행 중인 프로그램의 위치(전체 경로)를 찾을 수 있는 방법이 있는가?

의문)의.argv[0]전체 경로를 제공하지 않는다는 것이다.)

요약하면:

  • Unix를 /proc정말로 직선적이고 실현 가능한 방법은 다음과 같다.

    • readlink("/proc/self/exe", buf, bufsize)(리눅스)

    • readlink("/proc/curproc/file", buf, bufsize)FreeB)SD)

    • 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 실행 파일).

  • 에서 사용: 용GetModuleFileName(NULL, buf, bufsize)

Windows를 사용하는 경우 GetModuleFileName() 기능을 사용하십시오.

유닉스 시스템에서는 바이너리가 시작된 이후 바이너리가 제거되었을 수 있다는 점을 기억하십시오.그것은 유닉스에서는 완벽하게 합법적이고 안전하다.마지막으로 Windows에서 실행 중인 바이너리를 제거할 수 없음을 확인하십시오.

/symp/self/exe는 여전히 읽을 수 있지만 실제로 작동하는 symlink는 아닐 것이다.그것은...기묘한

사실은 대답이 아니라 그냥 명심해야 할 쪽지야.

우리가 알 수 있듯이 실행 가능한 실행 파일의 위치를 찾는 문제는 상당히 까다롭고 리눅스나 유닉스에서는 플랫폼에 특화되어 있다.그 일을 하기 전에 다시 한번 생각해야 한다.

일부 구성 또는 리소스 파일을 검색하기 위해 실행 가능한 위치가 필요한 경우, 시스템에 파일을 배치하는 Unix 방법을 따라야 할 수 있다./etc, 또는/usr/local/etc또는 현재 사용자 홈 디렉토리에/usr/share리소스 파일을 저장할 수 있는 좋은 위치.

Mac OS X에서는 를 사용하십시오.

이와 유사한 질문에 대한 을 참조하십시오.

다음 설명은 유닉스 전용입니다.

이 질문에 대한 현학적인 대답은 모든 경우에 이 질문에 정확하게 대답할 수 있는 일반적인 방법은 없다는 것이다.당신이 알아낸 바와 같이, argv[0]는 상위 프로세스에 의해 어떤 것으로도 설정될 수 있으므로, 프로그램의 실제 이름이나 파일 시스템의 위치와 어떠한 관계도 가질 필요가 없다.

그러나 다음과 같은 휴리스틱이 작용하는 경우가 많다.

  1. argv[0]가 절대 경로인 경우, 이 경로가 실행 파일의 전체 경로라고 가정하십시오.
  2. argv[0]가 상대 경로인 경우, 즉, a를 포함한다./, getcwd로 현재 작업 디렉토리를 결정한 다음 argv[0]를 여기에 추가하십시오.
  3. 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프로그램의 진짜 경로로 말이야그리고, 사실, 그것은 당신이 원했던 것이 아니라, 프로그램의 진정한 길이다.이 문제는 실제 하드 링크보다 훨씬 일반적인 심볼 링크에서는 발생하지 않는다는 점에 유의하십시오.

이 접근방식은 원칙적으로 신뢰할 수 없음에도 불구하고, 대부분의 목적에서 실제로 충분히 잘 작동한다.

많은 POSIX 시스템에서 /proc/PID/exe 아래에 있는 심링크를 확인할 수 있다.몇 가지 예:

# 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

리눅스의 경우/proc/self/exebinreloc이라고 불리는 멋진 도서관에 묶인 일을 하는 방법, 당신은 도서관을 다음에서 찾을 수 있다.

난 그럴거야.

1) basenameename 함수 사용: http://linux.die.net/man/3/basename
2) 그 디렉토리에 치드리게시
3) getpwd()를 사용하여 현재 디렉토리를 가져오기

그렇게 하면 ./ 또는 ../bin/ 대신 깔끔하고 완전한 형태로 디렉토리를 얻을 수 있을 것이다.

프로그램에 중요한 경우 현재 디렉터리를 저장하고 복원하십시오.

참조URL: https://stackoverflow.com/questions/933850/how-do-i-find-the-location-of-the-executable-in-c

반응형