根据虚拟主机名将虚拟主机提取到单个文件

根据虚拟主机名将虚拟主机提取到单个文件

我想从 /etc/apache2/sites-enabled/default-ssl.conf 中提取每个 VirtualHost 并将其放入自己的配置文件中

一个文件中有很多条目,管理它们日益成为问题,但是,将它们移动到每个虚拟主机的单独文件中很容易工作和管理。

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName www.customer1.com
    ServerAlias customer1.com
    DocumentRoot /var/www/customer1
    ErrorLog ${APACHE_LOG_DIR}/error.log
    LogLevel warn
    CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
    SSLEngine on
    SSLProtocol all
    SSLCipherSuite HIGH:MEDIUM
    SSLStrictSNIVHostCheck on
    SSLVerifyClient none
    SSLProxyEngine off
    SSLCertificateFile  /etc/apache2/ssl_certs/customer1.cert
    SSLCertificateKeyFile /etc/apache2/ssl_certs/customer1.key
    SSLCertificateChainFile /etc/apache2/ssl_certs/customer1.inter.cert
    <Directory /var/www/customer1>
    Options -Indexes
    AllowOverride All
    </Directory>

我正在尝试类似的方法,但它不允许我根据 ServerName 值进行隔离。

awk '/^<VirtualHost/{flag=1}/^<\/VirtualHost/{print $2;flag=0}flag' /etc/apache2/sites-enabled/default-ssl.conf

答案1

给定一个名为 file.txt 的文件,其中包含以下输入:

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName name1

</VirtualHost>

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName name2

</VirtualHost>

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName name3

</VirtualHost>

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName name4

</VirtualHost>

以及一个名为 get-virtual-host.sh 的脚本,其内容为:

#!/bin/bash

if [ $# -ne 2 ]; then
    echo "Usage: get-virtual-host.sh <filename> <ServerName>"
    exit 1
fi

sed -ne "/^<VirtualHost/{x;:cycle n; /ServerName/{/ServerName[[:space:]]\+$2/!{s/.*//; x; d}}; /<\/VirtualHost/{H;x;p;q}; H; bcycle}" $1

然后您可以通过指定如下参数来获取 VirtualHost 部分:

get-virtual-host.sh file.txt name2

哪个输出

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName name2

</VirtualHost>

这是你需要的吗?

Sed 脚本按要求解释:

sed 命令说:

如果有一行以<虚拟主机, 请执行下列操作:

  1. 交换模式空间与保持空间
  2. 读取下一个输入行
  3. 如果它包含这个词服务器名称,检查 ServerName 的值是否等于给定脚本的参数 2
  4. 如果不相等,则删除模式空间中的所有内容,交换模式和保持空间,删除模式空间并使用下一个输入行启动 sed 命令。
  5. 如果相等,检查输入行是否包含结束标记</虚拟主机
  6. 如果是,则在保留空间中追加换行符,将模式空间追加到保留空间,交换模式和保留空间,打印内容并退出
  7. 否则,将换行符添加到保留空间,并将模式空间的内容添加到保留空间并跳转到标签循环(上面的步骤 2)

答案2

实际上,您希望在每个 处分割文件<VirtualHost,然后根据ServerName值重命名它们。

第一步:分割文件

csplit -z -f vhost_ '/<VirtualHost/' '{*}'

csplit允许在给定的模式匹配处分割文件,这里<VirtualHost包括的选项是:-f vhost_使用此前缀命名结果文件(新文件将为vhost_00, vhost_01, ....),-z不创建空文件,{*}在每个模式匹配处分割。更多内容可在man csplit

第 2 步:重命名文件

一个简单的 bash 例程应该可以解决问题:

for f in vhost_??
  do mv $f $(grep ServerName $f | awk '{print $2".conf"}')
done

你好像很熟悉awk所以bash就不解释了。

答案3

@Juxtaposed——我从 unix.com 小组认识你......你是这些事情的专家

这个解决方案对我来说非常有效——除了我必须这样做

egrep -v "^$|^#" default-ssl.conf|egrep ServerName |while read S N
do
./get-virtual-host.sh default-ssl.conf $N > configs/$N.conf
done

有些文件是空的——但我可以忍受——只有 2 个文件大小为 0,尽管它们也是完整的虚拟主机。

不管怎样,非常感谢你的帮助。

相关内容