如何在nginx中列出所有vhost

时间:2015-09-04 14:48:43

标签: linux shell nginx

是否有一个命令会列出在CentOS上运行在nginx下的所有vhost或服务器?我想将结果通过管道传输到文本文件中以进行报告。

我正在寻找类似于我用于Apache的命令:

apachectl -S 2>& 1 | grep'port 80'

8 个答案:

答案 0 :(得分:36)

从版本1.9.2开始,您可以:

nginx -T

显示完整的nginx配置

nginx -T | grep "server_name " #include the whitespace to exclude non relevant results

显示所有服务器名称

答案 1 :(得分:25)

<强>更新 感谢@Putnik指出一种更简单的方法(但我更喜欢只列出已启用网站的内容):

grep server_name /etc/nginx/sites-enabled/* -RiI

旧帖子:

尝试这样的事情:

find /etc/nginx/sites-enabled/ -type f -print0 | xargs -0 egrep '^(\s|\t)*server_name'

希望有所帮助!

答案 2 :(得分:16)

到目前为止的答案是有效的, 除了 如果你有server_name指令在多行上运行,那么它将无声地失败。它们似乎也是为人类消费而编写的(拾取server_name_in_redirect off;之类的额外行,因此您不能将它们包含在脚本中。

我有很多虚拟主机,并希望在脚本中使用输出(叹息),所以这里的东西要长得多,但应该足够强大,以达到这个目的:

nginx -T | sed -r -e 's/[ \t]*$//' -e 's/^[ \t]*//' -e 's/^#.*$//' -e 's/[ \t]*#.*$//' -e '/^$/d' | \
sed -e ':a;N;$!ba;s/\([^;\{\}]\)\n/\1 /g' | \
grep -P 'server_name[ \t]' | grep -v '\$' | grep '\.' | \
sed -r -e 's/(\S)[ \t]+(\S)/\1\n\2/g' -e 's/[\t ]//g' -e 's/;//' -e 's/server_name//' | \
sort | uniq | xargs -L1

由于它很长且\ - y,我将对每一行进行快速解释。

  1. 获取nginx以打印其整个配置(以便我们不必担心要包含哪些文件)并清理它:删除前导和尾随空格,注释(包括尾随的)和空行。
  2. 不应以分号或大括号结尾的每一行都应该继续,因此我们会在没有前一个\n;或{{1}的情况下替换任何{带空格。这需要使用sed的怪人}抓取整个文件技巧,并进行一些分组,以便我们可以将最后一个字符放回:a;N;$!ba;,再加上一堆额外的反斜杠以便运气。
  3. 现在我们可以提取每个\1行,并进行一些额外的检查以删除nginx变量(server_name)并仅包含有效域(即不是$foolocalhost
  4. 单词之间的任何制表符/空格都会转换为回车符,然后我们删除剩余空格(以防万一),分号和_部分。
  5. 最后对其进行排序,将其统一并使用server_name删除顶部的空白行。
  6. 请注意,这里有一些位技术上加倍,但我希望尽可能清晰和健壮。但欢迎提出改进建议。

答案 3 :(得分:14)

grep server_name /etc/nginx/* -RiI

Imho比@Haubix的答案快得多。 有选择地添加|grep -v "#"

答案 4 :(得分:1)

除了所有其他出色的解决方案之外,如果您只需要每行一个简单的所有名称列表,例如:

example.com
my.example.com
etc.com

解析配置。使用server_name获取所有行。删除server_name。最后,每行放置一个域。

sudo nginx -T | grep "server_name " | sed 's/.*server_name \(.*\);/\1/' | sed 's/ /\n/'

答案 5 :(得分:0)

您可以使用以下

一次列出一行
nginx_domains(){
    domains=`find /etc/nginx/ -type f -name "*.conf" -print0 | xargs -0 egrep '^(\s|\t)*server_name' | sed -r 's/(.*server_name\s*|;)//g'`
    for domain in $domains; do 
       echo $domain; 
    done
}

答案 6 :(得分:0)

@anthony-briggs正确地指出,如果您的server_name ... ;声明分散在多行中,则此处给出的大多数其他答案将无效。

但是,如果您可以负担得起perl口译员的负担,则可以缩短他对这种oneliner的解决方案:

nginx -T | perl -ln0777e '$,=$\; s/^\s*#.*\n//mg; print grep !$u{$_}++ && !m/^_$/, map m/(\S+)/g, m/\bserver_name\s++(.*?)\s*;/sg'

成块:

perl -l -n -0777 -e

-l:使print命令以换行符终止其输出;

这还会导致在读取每个输入记录时删除尾随的换行符,但这不会打扰我们,因为我们:

-n -0777:一口气将所有输入$_记录下来(一条记录);

-e:只需将下一个参数作为Perl源执行;


$, = $\ ;

使print命令还在其每个参数之间输出换行符;


s/^\s*#.*\n//mg ;

删除所有评论;

不管前导空格如何,都假定注释从行首开始一直延伸到行尾(.与此处的换行符不符;


m/\bserver_name\s++(.*?)\s*;/sg

产生所有server_name ... ;声明之间的所有内容({. 与此处的换行符匹配);


...全部map踩到:

map m/(\S+)/g, 

...将仅保留连续的非空白块;


...,然后对其进行grep-ped操作以确保唯一性,而不是是特殊的“ _”服务器名称,

grep !$u{$_}++ && !m/^_$/, 

...和print-ed(未排序)。

答案 7 :(得分:0)

grep server_name /etc/nginx/sites-enabled/* -RiI | grep -v "#" | awk -F ' ' ' { print $3 "\n" $4  "\n" $5 }' | sort | uniq