如何列出 nginx 中的所有虚拟主机
Posted
技术标签:
【中文标题】如何列出 nginx 中的所有虚拟主机【英文标题】:How can I list all vhosts in nginx 【发布时间】:2015-11-30 18:46:06 【问题描述】:是否有一个命令可以列出在 CentOS 上运行在 nginx 下的所有虚拟主机或服务器?我想将结果通过管道传输到文本文件中以用于报告目的。
我正在寻找类似于我用于 Apache 的这个命令的东西:
apachectl -S 2>&1 | grep '端口 80'
【问题讨论】:
这取决于你叫什么vhost
。 Nginx 的服务器块可以匹配任意数量的域。也许您想列出所有服务器块?
是的,服务器块可以工作。可能是端口 80 的那些。重点是列出所有网站以便生成托管计费。
【参考方案1】:
grep server_name /etc/nginx/sites-enabled/* -RiI | grep -v "#" | awk -F ' ' ' print $3 "\n" $4 "\n" $5 ' | sort | uniq
【讨论】:
【参考方案2】:@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 ;
删除所有cmets;
忽略前导空格,假设 cmets 开始并一直运行到行尾(.
此处不匹配换行符);
m/\bserver_name\s++(.*?)\s*;/sg
在所有 server_name ... ;
声明之间生成所有内容(.
是否在此处匹配换行符);
...都是map
-ped to:
map m/(\S+)/g,
...这将只留下连续的非空白块;
...然后 grep
-ped 是唯一性,不是是特殊的“_
”服务器名称,
grep !$u$_++ && !m/^_$/,
...和print
-ed(未排序)。
【讨论】:
【参考方案3】:除了所有其他出色的解决方案之外,如果您只需要每行一个所有名称的简单列表,例如:
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/'
【讨论】:
如果server_name
出现在任何其他 conf 文件中(例如,定义 log_format
的那个),你会得到不想要的匹配【参考方案4】:
到目前为止的答案都是有效的,除了如果你有server_name
指令在多行上运行,那么它会默默地失败。它们似乎也是为人类消费而编写的(选择像server_name_in_redirect off;
这样的额外行),因此您不能将它们包含在脚本中。
我有很多虚拟主机,并且想在脚本中使用输出(sigh),所以这里有一些更长的东西,但应该足够强大: p>
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,我将包括对每一行的快速解释。
-
让 nginx 打印其整个配置(这样我们就不必担心要包含哪些文件)并对其进行清理:删除前导和尾随空格、cmets(包括尾随的)和空行。
不以分号或花括号结尾的每一行都应该继续,所以我们用空格替换任何前面没有
;
、
或
的\n
。这需要使用 sed 的怪异:a;N;$!ba;
抓取整个文件的技巧,并进行一些分组,以便我们可以将最后一个字符放回 \1
,再加上一堆额外的反斜杠以求好运。
现在我们可以提取每个server_name
行,并通过一些额外的检查来删除 nginx 变量 ($foo
) 并且只包含有效域(即不包括 localhost
和 _
)。
单词之间的任何制表符/空格都会变成回车符,然后我们会删除多余的空格(以防万一)、分号和server_name
部分。
最后排序,uniqify,用xargs -L1
去掉顶部的一个空行。
请注意,这里有一些位在技术上加倍,但我希望尽可能清晰和健壮。不过,欢迎提出改进建议。
【讨论】:
这应该是公认的答案。所有其他人只抓取与“server_name”标签在同一行的域。我的大多数 nginx 配置文件都有由换行符分隔的其他域。【参考方案5】:从 1.9.2 版开始,您可以:
nginx -T
显示完整的 nginx 配置
nginx -T | grep "server_name " #include the whitespace to exclude non relevant results
显示所有服务器名称
【讨论】:
更好的答案,不假设配置目录结构,只显示 nginx 知道的内容。谢谢 耶!那应该是绿色检查的答案。就在问题的背景下。人们有时会躲起来! 这需要绿色勾号。并且可以修改以包含较低 Nginx 版本的当前答案。 true.. 我的站点目录是/etc/nginx/sites.d/
。所以接受的答案对我不起作用。
请注意,您可能还需要传递 -p
(例如,在 GitLab Omnibus 上:/opt/gitlab/embedded/sbin/nginx -p /var/opt/gitlab/nginx -T
)【参考方案6】:
您可以使用以下命令一次列出域
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
【讨论】:
这在大多数系统上都不起作用,只有核心配置文件以.conf
结尾,另外它会拉入像server_names_hash_bucket_size
这样的配置行【参考方案7】:
更新: 感谢@Putnik 指出了一种更简单的方法(但我更喜欢只列出启用的网站):
grep server_name /etc/nginx/sites-enabled/* -RiI
旧帖:
试试这样的:
find /etc/nginx/sites-enabled/ -type f -print0 | xargs -0 egrep '^(\s|\t)*server_name'
希望有帮助!
【讨论】:
这行得通,但我没有启用站点的文件夹,所以我删除了该部分。 如果您要托管数千个网站,您的某些 conf 文件可能会有多个由换行符分隔的域。这个答案不会捕捉到那些。请参阅下面最完整的 Anthony Briggs 的答案。 有人可以澄清RiI
选项的作用吗?
-R:递归,-i:忽略大小写,-I:忽略二进制文件
据我所知,/etc/nginx/sites-enabled/
是在基于 Debian 的系统上创建的(模仿 Apache)。这是一个优雅的解决方案,但不够通用【参考方案8】:
grep server_name /etc/nginx/* -RiI
恕我直言,输入速度比@Haubix 的答案快得多。
可选添加|grep -v "#"
【讨论】:
这是我最初的直观方法。顺便说一句,我认为您可能会丢失/*
,如果您只是输入目录名称,那么它将从该级别向下搜索以上是关于如何列出 nginx 中的所有虚拟主机的主要内容,如果未能解决你的问题,请参考以下文章
Symfony2:列出虚拟文件夹(Netbeans)中的所有视图/路由文件