精讀Nginx原始碼·自動指令碼篇(1)如何讀取配置選項?

鍾超發表於2012-03-07

精讀 Nginx 原始碼·自動指令碼篇(1)如何讀取配置選項?

  • Author: Poechant
  • Blog: blog.CSDN.net/Poechant
  • Email: zhongchao.ustc#gmail.com (#->@)
  • Date: March 4th, 2012
  • Copyright © 柳大·Poechant

在安裝Nginx之前(即執行make指令碼之前),首先是進行安裝的配置準備,包括環境檢查及生成檔案。這些工作是由自動指令碼完成的。和絕大多數軟體一樣,Nginx的自動指令碼的入口,同樣是名為configure的檔案。

除了configure,其他的自動指令碼都在auto目錄下。通過分析configure指令碼原始碼,我們可以看到,configure首先執行了auto目錄下的幾個自動指令碼,如下:

. auto/options
. auto/init
. auto/sources

其中通過執行auto/options指令碼,來設定配置選項。下面將逐步分析auto/options指令碼是如何工作的。

1 讀取configure配置引數

開始先宣告瞭 N 多變數,然後最主要的部分從這段開始:

opt=

for option
    do
    ...
done

這段實際上是處理執行./configure的時候攜帶的引數選項,for迴圈每次對應一個引數選項 option。要注意for迴圈體上面有一個全域性的opt變數。這個迴圈體內的第一個語句是最重要是,它是:

opt="$opt `echo $option | sed -e \"s/\(--[^=]*=\)\(.* .*\)/\1'\2'/\"`"

通過迴圈執行該語句後,opt的值就是一個由空格來分隔的引數列表。然後在迴圈體中接下來是一個case-esac,用來得到引數值,如下:

case "$option" in
    -*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
       *) value="" ;;
esac

其含義是將value賦值為引數選項值,如果選項值不與-*=*的模式匹配,則value值為""。接下來的case-esac語句用來匹配引數的型別。

    case "$option" in
        --help)                          help=yes                   ;;
        --prefix=)                       NGX_PREFIX="!"             ;;
        --prefix=*)                      NGX_PREFIX="$value"        ;;
        --sbin-path=*)                   NGX_SBIN_PATH="$value"     ;;
        --conf-path=*)                   NGX_CONF_PATH="$value"     ;;
        ...
    esac

各匹配的分支語句中進行配置變數的賦值。這些變數在auto/options指令碼的最開始處賦以預設值,其中那些模組配置變數被賦以YES的表示預設開啟,賦以NO的表示預設關閉。但它們開啟與否由這個auto/options中的case-esac語句來決定。還有一些是安裝相關的選項變數也在這裡被賦值,比如:

  • prefix引數值被賦予NGX_PREFIX
  • sbin-path引數值被賦予NGX_SBIN_PATH
  • conf-path引數值被賦予NGX_CONF_PATH
  • error-log-path引數值被賦予NGX_ERROR_LOG_PATH
  • pid-path引數值被賦予NGX_PID_PATH
  • lock-path引數值被賦予NGX_LOCK_PATH

如果option並不符合預設的這些匹配,也就是使用者使用configure指令碼的時候攜帶的引數錯誤,則auto/options會匹配該語句:

*)
    echo "$0: error: invalid option \"$option\""
    exit 1

從而提示使用者引數錯誤,並使指令碼退出執行。經過多次迴圈,for-do-done就結束。

2 設定NGX_CONFIGURE變數

處理完所有option後,opt就如我們上面提到的,成為由空格分割的配置項值,並被賦給NGX_CONFIGURE變數:

NGX_CONFIGURE="$opt"

3 是否顯示configure的幫助資訊

再看下面這句:

if [ $help = yes ]; then
cat << END
    …
END
    exit 1
fi

預設情況下$help變數值在初始化時就為no。如果configure選項中指定了help引數,則$help引數為yes,則會執行cat命令,顯示大段的幫助資訊,然後退出。

4 是否關閉 HTTP 功能

預設情況下HTTP的一些基本功能是被開啟的,如果使用者指定了--without-http引數,則變數HTTP會被賦值為NO,則下面這段程式碼if-fi中的語句會被執行:

if [ $HTTP = NO ]; then
    HTTP_CHARSET=NO
    HTTP_GZIP=NO
    HTTP_SSI=NO
    HTTP_USERID=NO
    HTTP_ACCESS=NO
    HTTP_STATUS=NO
    HTTP_REWRITE=NO
    HTTP_PROXY=NO
    HTTP_FASTCGI=NO
fi

5 是否指定執行於 Windows 平臺

如果顯式指定了--crossbuild引數,則變數NGX_PLATFORM會被賦予當前for-do-done迴圈中的"$value"值,也就是--crossbuild的引數值,一般在考慮在Windows平臺使用時才會用到,看下面的語句:

if [ ".$NGX_PLATFORM" = ".win32" ]; then
    NGX_WINE=$WINE
fi

如果指定--crossbuild=win32,則NGX_WINE就會被賦值了。

6 Nginx 配置檔案路徑

在載入configure的引數時,如果沒有指定了--conf-path引數,則$NGX_CONF_PATH變數是沒有值的,則下面的語句會為NGX_CONF_PATH賦以conf/nginx.conf的預設值。不過我在想老毛子 Igor Sysoev 同學完全可以在auto/options開始處和其他引數一樣先指定NGX_CONF_PATH的預設值。

NGX_CONF_PATH=${NGX_CONF_PATH:-conf/nginx.conf}

然後獲取配置檔案所在目錄的:

NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`

如果指定引數--conf-path=/home/michael/nginx/conf/nginx.conf,則NGX_CONF_PREFIX的值就是/home/michael/nginx/conf

7 Nginx 程式 ID 檔案和鎖檔案路徑

下面是同樣的方式初始化NGX_PID_PATHNGX_LOCK_PATH,分別對應configure引數--pid-path--lock-path,其預設值分別為logs/nginx.pidlogs/nginx.lock

NGX_PID_PATH=${NGX_PID_PATH:-logs/nginx.pid}
NGX_LOCK_PATH=${NGX_LOCK_PATH:-logs/nginx.lock}

8 錯誤日誌檔案路徑

如果指定了引數--error-log-pathNGX_ERROR_LOG_PATH變數的值會被指定,根據下面的語句,如果指定的是stderr則將NGX_ERROR_LOG_PATH修改為空,即不需要錯誤日誌檔案。如果不是標準輸出,且其值為空,則設定為預設值logs/error.log

if [ ".$NGX_ERROR_LOG_PATH" = ".stderr" ]; then
    NGX_ERROR_LOG_PATH=
else
    NGX_ERROR_LOG_PATH=${NGX_ERROR_LOG_PATH:-logs/error.log}
fi

9 HTTP 相關各路徑

NGX_HTTP_LOG_PATH=${NGX_HTTP_LOG_PATH:-logs/access.log}
NGX_HTTP_CLIENT_TEMP_PATH=${NGX_HTTP_CLIENT_TEMP_PATH:-client_body_temp}
NGX_HTTP_PROXY_TEMP_PATH=${NGX_HTTP_PROXY_TEMP_PATH:-proxy_temp}
NGX_HTTP_FASTCGI_TEMP_PATH=${NGX_HTTP_FASTCGI_TEMP_PATH:-fastcgi_temp}
NGX_HTTP_UWSGI_TEMP_PATH=${NGX_HTTP_UWSGI_TEMP_PATH:-uwsgi_temp}
NGX_HTTP_SCGI_TEMP_PATH=${NGX_HTTP_SCGI_TEMP_PATH:-scgi_temp}

10 Perl 模組

如果指定了--with-perl_modules_path引數,則NGX_PERL_MODULES變數即被設定。如果指定的值為一個絕對路徑或未指定(空),則當做相對路徑來處理,設定為$NGX_PREFIX/$NGX_PERL_MODULES

case ".$NGX_PERL_MODULES" in
    ./*)
    ;;

    .)
    ;;

    *)
        NGX_PERL_MODULES=$NGX_PREFIX/$NGX_PERL_MODULES
    ;;
esac

11 小結

通過執行auto/options指令碼,所有的配置項已經被正確解析並載入到相應的配置變數中了。

-

轉載請註明來自“柳大的CSDN部落格”:blog.csdn.net/Poechant

-

相關文章