nginxの設定ファイルからbashで値を取得する話

nginxの設定ファイルには、ドメイン名やドキュメントルートなどの重要な情報が書かれています。
この記事では、それらの値をbashコマンドで取得する方法を、コマンドの仕組みも解説します。

前提:設定ファイルのパスを変数に入れておく

export NGINX_CONF_FILE=/etc/nginx/vhosts/001-default.conf

export を使って変数に設定ファイルのパスを入れておくことで、以降のコマンドを短く書けます。
/etc/nginx/vhosts/001-default.conf の部分は、ご自身の環境に合わせて変更してください。


ドメイン名を取得する

export DOMAIN=$(sed -n 's/^[ \t]*server_name[ \t]*\(.*\);/\1/p' "${NGINX_CONF_FILE}")

コマンドの解説

sed は、テキストを1行ずつ処理するコマンドです。
ここでは s/検索パターン/置換後/p という形式(正規表現による置換)を使っています。

オプション・パターン意味
-nデフォルトの出力を抑制する(マッチした行だけ出力したいときに使う)
^[ \t]*行頭の空白・タブを読み飛ばす
server_name[ \t]*server_name というキーワードと、その後の空白・タブにマッチ
\(.*\)それ以降の文字列をグループとしてキャプチャ(\1 で参照できる)
;行末のセミコロンまでをマッチ対象にする
/\1/pキャプチャした部分だけを出力する

つまり server_name sample.example.com; という行から、sample.example.com だけを取り出しています。


ドキュメントルートを取得する

export DOCUMENT_ROOT=$(sed -n 's/^[ \t]*root[ \t]*\(.*\);/\1/p' "${NGINX_CONF_FILE}")

コマンドの解説

ドメイン取得と同じ仕組みで、server_name の代わりに root をキーワードに検索しています。

root /var/www/httpdocs/public; という行から、/var/www/httpdocs/public だけを取り出します。

注意: 設定ファイル内にコメントアウトされた root の行(# root ...)がある場合、^[ \t]*# にはマッチしないため、自動的に除外されます。


アクセスログのディレクトリを取得する

export ACCESS_LOG_PATH=$(sed -n 's/^[ \t]*access_log[ \t]*\(.*\);/\1/p' "${NGINX_CONF_FILE}" | awk '{print $1}' | xargs dirname)

コマンドの解説

access_log /var/log/nginx/access.log main; のように、値の後にフォーマット名(main など)が続くことがあります。そのため、3つのコマンドをパイプ(|)でつないで処理しています。

  1. sed で行を抽出する
    access_log の行から ; までの部分(/var/log/nginx/access.log main)を取り出します。
  2. awk '{print $1}' でファイルパスだけ取り出す
    スペース区切りの1番目の要素(/var/log/nginx/access.log)だけを出力します。フォーマット名(main)を取り除く目的です。
  3. xargs dirname でディレクトリ部分を取り出す
    dirname はファイルパスからディレクトリ部分を返すコマンドです。/var/log/nginx/access.log/var/log/nginx になります。xargs は前のコマンドの出力を dirname の引数として渡すために使います。

利用例:Laravelのログディレクトリを取得する

Laravelでは、ドキュメントルートが プロジェクトルート/public になっています。
そのため dirname で1階層上がるとプロジェクトルートが得られ、そこから storage/logs への絶対パスを組み立てられます。

export DOCUMENT_ROOT=$(sed -n 's/^[ \t]*root[ \t]*\(.*\);/\1/p' "${NGINX_CONF_FILE}")
export APP_ROOT=$(dirname "${DOCUMENT_ROOT}")
export APP_LOG_PATH=${APP_ROOT}/storage/logs

たとえば DOCUMENT_ROOT/var/www/httpdocs/public の場合、以下のようになります。

変数
DOCUMENT_ROOT/var/www/httpdocs/public
APP_ROOT/var/www/httpdocs
APP_LOG_PATH/var/www/httpdocs/storage/logs

参考:nginx.conf の設定例(抜粋)

server {
    listen       80;
    listen       [::]:80;
    server_name  sample.example.com;
#   root         /var/www/httpdocs;
    root         /var/www/httpdocs/public;

    location / {
        index index.php index.html index.htm;
        try_files $uri $uri/index.html $uri/index.htm /index.php?$args;
    }

    # ログ出力先の定義
    access_log /var/log/nginx/access.log main;
    error_log  /var/log/nginx/error.log;
    ...
}