現在実行中のプログラムの絶対パス

現在実行中のプログラムの絶対パス

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。もちろん、プログラムがビルドパスにインストールされている場合にのみ当てはまります。

おすすめ記事