zoukankan      html  css  js  c++  java
  • 解析启动参数:ngx_get_options()函数(113资讯网)

    分析ngx_get_options()函数
    
    这个函数的作用就是解析nginx的启动命令传递的参数,
    比如/usr/local/nginx/sbin/nginx -s reload, /usr/local/nginx/sbin/nginx -t等
    
    http://nginx.org/en/docs/switches.html
    
    nginx supports the following command-line parameters:
    
    -? | -h — print help for command-line parameters.
    
    -c fileuse an alternative configuration file instead of a default file.
    
    -g directives — set global configuration directives, for example,
    nginx -g "pid /var/run/nginx.pid; worker_processes `sysctl -n hw.ncpu`;"
    
    -p prefix — set nginx path prefix, i.e. a directory that will keep server files (default value is /usr/local/nginx).
    
    -q — suppress non-error messages during configuration testing.不输出error级别下的信息,配合-t参数使用
    
    -s signal — send a signal to the master process. The argument signal can be one of:
        stop — shut down quickly
        quit — shut down gracefully
        reload — reload configuration, start the new worker process with a new configuration, gracefully shut down old worker processes.
        reopen — reopen log files
    
    -t — test the configuration file: nginx checks the configuration for correct syntax, and then tries to open files referred in the configuration.
    
    -T — same as -t, but additionally dump configuration files to standard output (1.9.2).
    
    -v — print nginx version.
    
    -V — print nginx version, compiler version, and configure parameters.
    
    
    我们先看一下ngx_get_options的源码,如下:
    
    static ngx_int_t
    ngx_get_options(int argc, char *const *argv)
    {
        u_char     *p;
        ngx_int_t   i;
    // 第0个参数是nginx本身,所以从第一个参数进行解析
        for (i = 1; i < argc; i++) {
    
            p = (u_char *) argv[i];
    // 参数必须以短横线开头
            if (*p++ != '-') {
                ngx_log_stderr(0, "invalid option: "%s"", argv[i]);
                return NGX_ERROR;
            }
    
            while (*p) {
    
                switch (*p++) {
    
                case '?':
                case 'h':
                    ngx_show_version = 1;
                    ngx_show_help = 1;
                    break;
    
                case 'v':
                    ngx_show_version = 1;
                    break;
    
                case 'V':
                    ngx_show_version = 1;
                    ngx_show_configure = 1;
                    break;
    
                case 't':
                    ngx_test_config = 1;
                    break;
    
                case 'T':
                    ngx_test_config = 1;
                    ngx_dump_config = 1;
                    break;
    
                case 'q':
                    ngx_quiet_mode = 1;
                    break;
    
                case 'p':
                    if (*p) {
                        ngx_prefix = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_prefix = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-p" requires directory name");
                    return NGX_ERROR;
    
                case 'c':
                    if (*p) {
                        ngx_conf_file = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_conf_file = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-c" requires file name");
                    return NGX_ERROR;
    
                case 'g':
                    if (*p) {
                        ngx_conf_params = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_conf_params = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-g" requires parameter");
                    return NGX_ERROR;
    
                case 's':
                    if (*p) {
                        ngx_signal = (char *) p;
    
                    } else if (argv[++i]) {
                        ngx_signal = argv[i];
    
                    } else {
                        ngx_log_stderr(0, "option "-s" requires parameter");
                        return NGX_ERROR;
                    }
    
                    if (ngx_strcmp(ngx_signal, "stop") == 0
                        || ngx_strcmp(ngx_signal, "quit") == 0
                        || ngx_strcmp(ngx_signal, "reopen") == 0
                        || ngx_strcmp(ngx_signal, "reload") == 0)
                    {
                        ngx_process = NGX_PROCESS_SIGNALLER;
                        goto next;
                    }
    
                    ngx_log_stderr(0, "invalid option: "-s %s"", ngx_signal);
                    return NGX_ERROR;
    
                default:
                    ngx_log_stderr(0, "invalid option: "%c"", *(p - 1));
                    return NGX_ERROR;
                }
            }
    
        next:
    
            continue;
        }
    
        return NGX_OK;
    }
    
    
    Q1: 为什么有一个while循环?
    A1: 一个减号后面可以带有多个参数。比如-thv等。
    Q2: 为什么处理-p的时候要先判断一下if(*p)呢?
    
    // 为什么要先判断一次 *p, 然后再判断argv[++i]呢?
             if (*p) {
                        ngx_prefix = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_prefix = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-p" requires directory name");
                    return NGX_ERROR;
    
    
    A2: 因为nginx的-p的参数既可以紧跟着p,也可以和-p中间隔若干个空格。
    比如/usr/local/nginx/sbin/nginx -p/usr/local/nginx/html/,也可以/usr/local/nginx/sbin/nginx -p /usr/local/nginx/html/,所以这里有两种处理方式了。
    if(*p)是处理第一种中间没有空格的情况。
    
    要知道,argv[]是一个字符串指针数组,每个元素都是以结尾的,并且数组的最后一个元素是NULL。所以如果*p != NULL,那么就说明-p的参数是紧挨着-p的。
    
    从这里我们也可以看出来,处理完-p指令之后执行了goto next,而不是break,这里也说明:如果-p指令和其他指令一起使用的时候,-p必须放到最后,比如/usr/local/nginx/sbin/nginx -tp /usr/local/nginx/html/, 而不能是/usr/local/nginx/sbin/nginx -pt /usr/local/nginx/html/。(注意p和t的顺序)
    
    对于每种参数的解析都是类似的,会设置一个变量。
    比如,如果是-v,那么就会设置ngx_show_version = 1等。
    
    文章原文地址:https://www.113p.cn/297.html
  • 相关阅读:
    神奇的python系列10:函数(三)
    神奇的python系列9:函数(二)
    神奇的python系列8:函数(一)
    神奇的python系列7:文件操作
    神奇的python系列6:python基础数据类型补充
    神奇的python系列5:python基础数据类型三(字典)
    神奇的python系列4:python基础数据类型二(列表)
    神奇的python系列3:python基础数据类型一
    神奇的python系列2:python基础一
    Token机制,session机制
  • 原文地址:https://www.cnblogs.com/113p/p/13226145.html
Copyright © 2011-2022 走看看