GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara menemukan lokasi yang dapat dieksekusi di C?

Sebenarnya bukan jawaban, tapi hanya catatan untuk diingat.

Seperti yang bisa kita lihat, masalah menemukan lokasi menjalankan executable cukup rumit dan khusus platform di Linux dan Unix. Seseorang harus berpikir dua kali sebelum melakukan itu.

Jika Anda memerlukan lokasi yang dapat dieksekusi untuk menemukan beberapa file konfigurasi atau sumber daya, mungkin Anda harus mengikuti cara Unix menempatkan file di sistem:letakkan konfigurasi ke /etc atau /usr/local/etc atau di direktori home pengguna saat ini, dan /usr/share adalah tempat yang bagus untuk meletakkan file sumber daya Anda.


Gunakan fungsi GetModuleFileName() jika Anda menggunakan Windows.


Harap perhatikan bahwa komentar berikut hanya untuk unix.

Jawaban bertele-tele untuk pertanyaan ini adalah bahwa tidak ada umum cara untuk menjawab pertanyaan ini dengan benar dalam semua kasus. Seperti yang telah Anda temukan, argv[0] dapat disetel ke apa pun oleh proses induk, sehingga tidak perlu memiliki hubungan apa pun dengan nama sebenarnya dari program atau lokasinya di sistem file.

Namun, heuristik berikut sering berhasil:

  1. Jika argv[0] adalah jalur absolut, asumsikan ini adalah jalur lengkap ke yang dapat dieksekusi.
  2. Jika argv[0] adalah jalur relatif, yaitu berisi / , tentukan direktori kerja saat ini dengan getcwd() dan kemudian tambahkan argv[0] padanya.
  3. Jika argv[0] adalah kata biasa, telusuri $PATH untuk mencari argv[0], dan tambahkan argv[0] ke direktori apa pun tempat Anda menemukannya.

Perhatikan bahwa semua ini dapat dielakkan oleh proses yang menjalankan program yang dimaksud. Terakhir, Anda dapat menggunakan teknik khusus linux, seperti yang disebutkan oleh emg-2. Mungkin ada teknik yang setara pada sistem operasi lain.

Bahkan seandainya langkah-langkah di atas memberi Anda nama jalur yang valid, Anda mungkin masih belum memiliki nama jalur yang sebenarnya Anda inginkan (karena saya curiga yang sebenarnya ingin Anda lakukan adalah menemukan file konfigurasi di suatu tempat). Kehadiran tautan keras berarti Anda dapat mengalami situasi berikut:

-- 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

Sekarang, pendekatan di atas (termasuk, saya kira, /proc/$pid/exe) akan memberikan /some/where/else/foo sebagai jalur nyata ke program. Dan sebenarnya, itu adalah a jalur nyata ke program, bukan yang Anda inginkan. Perhatikan bahwa masalah ini tidak terjadi pada tautan simbolis yang jauh lebih umum dalam praktiknya daripada tautan keras.

Terlepas dari kenyataan bahwa pendekatan ini pada prinsipnya tidak dapat diandalkan, dalam praktiknya ia bekerja cukup baik untuk sebagian besar tujuan.


Untuk meringkas:

  • Di Unix dengan /proc cara yang benar-benar lurus dan dapat diandalkan adalah dengan:

    • readlink("/proc/self/exe", buf, bufsize) (Linux)

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

    • readlink("/proc/self/path/a.out", buf, bufsize) (Solaris)

  • Di Unix tanpa /proc (yaitu jika di atas gagal):

    • Jika argv[0] dimulai dengan "/" (jalur absolut), inilah jalurnya.

    • Kalau tidak, jika argv[0] berisi "/" (jalur relatif) tambahkan ke cwd (dengan asumsi belum diubah).

    • Jika tidak, cari direktori di $PATH untuk argv[0] yang dapat dieksekusi .

    Setelah itu mungkin masuk akal untuk memeriksa apakah yang dapat dieksekusi sebenarnya bukan symlink. Jika diselesaikan, itu relatif terhadap direktori symlink.

    Langkah ini tidak diperlukan dalam metode /proc (setidaknya untuk Linux). Di sana symlink proc mengarah langsung ke executable.

    Perhatikan bahwa terserah pada proses pemanggilan untuk menyetel argv[0] benar. Sebagian besar benar, namun ada kalanya proses pemanggilan tidak dapat dipercaya (mis. setuid dapat dieksekusi).

  • Di Windows:gunakan GetModuleFileName(NULL, buf, bufsize)


Linux
  1. Cara mengaudit izin dengan perintah find

  2. Bagaimana menemukan jalur instal git di Mac atau Linux?

  3. Bagaimana cara menemukan UUID dari sistem file

  1. Cara Mengetahui Apakah Disk Adalah SSD Atau HDD Di Linux

  2. Bagaimana menerapkan readlink untuk menemukan jalan

  3. Bagaimana cara menemukan ukuran tumpukan maksimum?

  1. Cara mem-pipe hasil 'find' ke mv di Linux

  2. bagaimana menemukan jalur HADOOP_HOME di Linux?

  3. Bagaimana menemukan pengelola file default?