Shell-Script

Bash 腳本無法將變數辨識為路徑的一部分

  • August 11, 2017

這個 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 中是否列印了某些內容是不夠的。您需要確保變數在環境中。如果你只做 run OSSIEHOME=/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 程序中執行,它將以相同的權限執行。

¹對於高級使用者,請添加“除非您知道為什麼需要省略它們”。

引用自:https://unix.stackexchange.com/questions/385258