在 Ubuntu Linux 16.04 Lenovo Thinkstation 桌面上運行的 C# 可執行檔在哪裡運行,該桌面使用 DLLImport 的共用物件 (so) 在運行時查找共用物件的原始程式碼?即使共用物件 libxyz.so 與 C# 執行檔的子目錄位於同一子目錄中,我發現有必要匯出 LD_LIBRARY_PATH 以確保正確的 C# 執行程式行為。為什麼會這樣呢?
我們注意到,在許多第三方Linux軟體產品的安裝過程中,安裝程式或腳本會在子目錄/usr/libx86_64-linux-gnu中找到libc.so.6,而不需要客戶指定包含該子目錄的LD_LIBRARY_PATH。為什麼會這樣呢?
另外,如果我們希望將 C# 可執行檔作為點按單一服務運行,我們如何全域指定 LD_LIBRARY_PATH,直到電腦重新啟動,而不需要開啟 Ubuntu Linux 16.04 終端機?有沒有比將 LD_LIBRARY_PATH 作為 envp 參數傳遞給 execle 更優雅的方法?
答案1
我將嘗試為您回答這個問題的所有三個部分
【為什麼】需要導出LD_LIBRARY_PATH以確保正確的C#可執行程式行為
安裝程式或腳本設法在子目錄 /usr/libx86_64-linux-gnu 中找到 libc.so.6,而不需要客戶指定 LD_LIBRARY_PATH
連結庫是從一組已知位置引用的。通常這些是系統目錄,以便特權代碼可以安全地使用它們(它們不能被使用者覆蓋)。
一旦你理解了這一點,你就會意識到已知位置的集合不能不包括.
。您可以透過檢查文字檔案來查看一組已知位置/etc/ld.so.conf
。如果你編輯它,你必須運行ldconfig
以更新其相應的二進位資料庫。
可以透過使用 的實例來擴展每個應用程式的已知位置集LD_LIBRARY_PATH
,該實例採用冒號分隔的目錄清單進行搜尋。如果你使用這個,核心會放棄程式的所有權限 - 所以你不能用它來欺騙passwd
或sudo
,例如。
我們如何全域指定 LD_LIBRARY_PATH,直到電腦重新啟動 [...] 有沒有比將 LD_LIBRARY_PATH 作為 envp 參數傳遞給 execle 更優雅的方法?
在全域範圍內設定它是一個非常糟糕的主意,因為它會破壞sudo
、passwd
和其他特權程式。不過,我不明白為什麼不能LD_LIBRARY_PATH
在每個應用程式的 shell 腳本中進行設定。您不需要將其作為“終端程式”啟動,因為它不會向終端寫入任何重要內容
#!/bin/bash
#
APP_DIR=/path/to/application
APP_DIR_LIB="$APP_DIR/lib"
APP_DIR_EXE="$APP_DIR/someprogram.exe"
export LD_LIBRARY_PATH="$APP_LIB_DIR"${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
exec "$APP_DIR_EXE" "$@"
echo "Ooops" >&2
exit 1
我用過"$@"
這樣的方式,傳遞給腳本的任何參數都會應用於可執行檔本身。
我不知道如何啟動或停止單一服務,所以我無法幫助您了解具體細節。如果您更新您的問題,我會看看是否可以在此處添加任何內容。