分析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 file — use 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