현재 실행 중인 프로그램의 절대 경로

현재 실행 중인 프로그램의 절대 경로

argv[0]현재 프로세스를 로드하게 만든 쉘 명령을 참조합니다. getcwd()현재 작업 디렉토리로 돌아갑니다. 이 정보를 통해 프로그램의 바이너리 실행 파일에 대한 절대 경로를 구성할 수 있습니까? 프로그램이 cd처음 로드된 이후 이미 완료된 경우에는 작동하지 않기를 바랍니다.

답변1

프로그래밍 언어 인터프리터 내에서 다음 코드를 사용하여 자체 경로를 가져옵니다.

Linux, Windows(Cygwin 포함), Mac 및 Solaris용 특수 코드가 있습니다.

#if __APPLE__
#include <mach-o/dyld.h>
#endif

#if __linux__
static val get_self_path(void)
{
  char self[PATH_MAX] = { 0 };
  int nchar = readlink("/proc/self/exe", self, sizeof self);

  if (nchar < 0 || nchar >= convert(int, sizeof self))         
    return nil;
  return string_utf8(self);
}
#elif HAVE_WINDOWS_H
static val get_self_path(void)
{
  wchar_t self[MAX_PATH] = { 0 };
  DWORD nchar;

  SetLastError(0);
  nchar = GetModuleFileNameW(NULL, self, MAX_PATH);

  if (nchar == 0 ||
      (nchar == MAX_PATH &&
       ((GetLastError() == ERROR_INSUFFICIENT_BUFFER) ||
        (self[MAX_PATH - 1] != 0))))
    return nil;

  return string(self);
}
#elif __APPLE__
static val get_self_path(void)
{
  char self[PATH_MAX] = { 0 };
  uint32_t size = sizeof self;

  if (_NSGetExecutablePath(self, &size) != 0)
    return nil;
  return string_utf8(self);
}
#elif HAVE_GETEXECNAME
static val get_self_path(void)
{
  val execname = string_utf8(getexecname());
  if (car(execname) == chr('/'))
    return execname;
  return scat3(getcwd_wrap(), chr('/'), execname);
}
#else
static val get_self_path(void)
{
  char self[PATH_MAX];

  if (argv[0] && realpath(argv[0], self))
    return string_utf8(self);

   return lit(HARD_INSTALLATION_PATH);
}
#endif

유형 val, 기호 및 nil함수는 인터프리터 내부에 있습니다. 그냥 추상 캐스팅 매크로입니다. 물론 일부 헤더 파일도 필요합니다.stringstring_utf8convertreadlinkrealpath

getexecname기능은 Solaris의 것입니다. 어떤 이유로 절대 경로를 얻으려면 현재 디렉터리를 붙여넣어야 하는 상대 경로를 처리하는 상황에서 코딩하고 있는 것 같습니다.

대체 전략은 argv[0]from 을 main사용할 수 있는 경우 realpath이를 호출하고 실행하는 것입니다. 이를 사용할 수 없는 경우 argv[0]변수의 하드코딩된 설치 경로를 사용합니다 Makefile. 예를 들어, 프로그램이 로 설치된 경우 /usr/bin/foo레시피 Makefile는 이를 컴파일러 명령줄에 로 삽입합니다 -DHARD_INSTALLATION_PATH=/usr/bin/foo. 물론 이는 프로그램이 빌드 경로에 설치된 경우에만 해당됩니다.

답변2

Linux에서는 심볼릭 링크를 사용할 수 있습니다/proc/self/exe

$ ls -l  /proc/self/exe
lrwxrwxrwx 1 rudi users 0 2016-10-18 16:20 /proc/self/exe -> /usr/bin/ls

관련 정보