Bash 腳本無法將變數辨識為路徑的一部分
這個 if 語句:
if [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then OSSIE_AC_INCLUDE=${OSSIEHOME}/share/aclocal/ossie else echo "Error: Cannot find the OSSIE aclocal files. This is not expected!"
始終預設為錯誤消息。我知道這
OSSIEHOME
是有價值的,因為如果我echo $OSSIEHOME
從命令行執行,我會得到/usr/local/redhawk/core
然後,如果我將該路徑硬編碼到我的腳本中,它就可以正常工作。問題是,我還有其他一些更大的腳本,其中無法選擇正確的路徑並對其進行硬編碼。我究竟做錯了什麼?
編輯:
od -c <<<"$OSSIEHOME"
給我這個:0000000 / u s r / l o c a l / r e d h a 0000020 w k / c o r e \n 0000030
ls -l /usr/local/redhawk/core/share/aclocal/
給了我這個:drwxr-xr-x 2 root root 4096 Jul 19 10:02 ossie
執行腳本
bash -x
給出:+ rm -f config.cache + '[' -e /usr/local/share/aclocal/libtool.m4 ']' + '[' -e /usr/share/aclocal/libtool.m4 ']' + /bin/cp /usr/share/aclocal/libtool.m4 acinclude.m4 + libtoolize --force --automake + '[' -n ']' + '[' -d /share/aclocal/ossie ']' + echo 'Error: Cannot find the OSSIE aclocal files. This is not expected!' Error: Cannot find the OSSIE aclocal files. This is not expected! + '[' -n ']' + aclocal -I aclocal: error: option '-I' requires an argument aclocal: Try '/bin/aclocal --help' for more information. + autoconf + automake --foreign --add-missing
我試圖導出
OSSIEHOME
以使其全球化(以防萬一),但這沒有用。然後我嘗試執行腳本,. script.sh
問題source script.sh
是我需要使用 sudo 執行腳本,否則它沒有必要的權限來工作。如果我這樣做了,但我得到了錯誤sudo: source: command not found
該問題已在問題的評論中診斷出來。在我的回答中,我將解釋發生了什麼以及如何解決它。
編碼
if [ -n ${OSSIEHOME} ] && [ -d ${OSSIEHOME}/share/aclocal/ossie ]; then
很危險,因為您使用的是未引用的變數擴展。
"${OSSIEHOME}"
或者只是"$OSSIEHOME"
擴展為變數的值,但${OSSIEHOME}
外部引號被拆分為單詞。特別是,如果變數為空或未設置,則&&
運算符左側的命令將擴展[
-n
]
為 true。您可以在執行時產生的跟踪中bash -x
看到[
-n
]
。請參閱為什麼我的 shell 腳本會因空格或其他特殊字元而窒息?更多細節。從現在開始,請記住始終將雙引號括在變數和命令替換中¹。if [ -n "${OSSIEHOME}" ] && [ -d "${OSSIEHOME}/share/aclocal/ossie" ]; then …
這將修復損壞的錯誤報告。但是您仍然需要確保在腳本執行時設置了變數。
echo $OSSIEHOME
僅檢查目前 shell 中是否列印了某些內容是不夠的。您需要確保變數在環境中。如果你只做 runOSSIEHOME=/usr/local/redhawk/core
,那隻會設置一個 shell 變數。要設置環境變數,您需要執行export OSSIEHOME=/usr/local/redhawk/core
(或OSSIEHOME=/usr/local/redhawk/core
然後export OSSIEHOME
)。您補充說您正在通過
sudo
. 在典型配置中,sudo 會從環境中刪除大多數變數。(當使用者只被允許執行特定命令時,這對於安全性至關重要,但如果允許您使用 sudo 執行任意命令,這將是一個沒有任何強大安全優勢的煩惱。)因此,您需要明確告訴 sudo 在何時設置此變數你執行腳本。sudo OSSIEHOME=/usr/local/redhawk/core /path/to/your/script
如果變數已經在 shell 的環境中設置並且您不想重複該值,則可以使用
sudo OSSIEHOME="$OSSIEHOME" /path/to/your/script
或者,您可能會或可能不會被允許執行
sudo -E /path/to/your/script
. 該-E
選項告訴 sudo 保留大多數環境變數。執行
source
或.
使用 sudo 不起作用,因為這些是 shell 內置命令,而不是可執行命令。它們是 shell 內置的,因為它們的作用是:在已經執行的同一 shell 中執行腳本,即它是 shell 中的一條指令,用於從文件中讀取命令,而不是執行單獨程序的指令。這對 sudo 沒有任何意義:如果腳本在同一個 shell 程序中執行,它將以相同的權限執行。¹對於高級使用者,請添加“除非您知道為什麼需要省略它們”。