Starting a series of posts with interesting Bash puzzles.
A puzzle about how to cut out part of an Apache config file.
Task: An Apache2 server running on CentOS v.6 has about 50 sites configured. Additional condition: they’re all described across at least three config files (their location unknown). You need to write a Bash script that pulls the settings for 4 sites out of the three config files and saves them either into separate files or into one single file. List of sites:
- website1.com
- website2.net
- website3.info
- website4.org
I figure there can be two types of readers:
- Those looking for the puzzle.
- Those looking for the solution.
For the second type of reader, here’s the script:
Unfold me
# Declare the list of sites
sites=(website1.com website2.net website3.info website4.org);
# Loop through the list of sites
for website in $sites;
do
# Get info about the config file that describes the host
config=$(apachectl -S 2>&1 |grep "80 namevhost $website" |cut -d "(" -f 2 |cut -d ":" -f1);
if [[ $config != "" ]];
then
# Find where the config starts
start=$(apachectl -S 2>&1 |grep "80 namevhost $website" |cut -d ":" -f 2 |cut -d ")" -f 1);
# Find where the config ends
eof=$(cat $config |wc -l)
end=$(cat -n $config |sed -n "$start,$eof"p |grep "</Virtual.ost>" |sed -n '1p' |awk '{print $1}');
# Cut the host settings out of the config
sed -n "$start","$end"p $config >> extracted_hosts.conf;
echo "" >> extracted_hosts.conf;
else
echo "check $website";
fi;
done
# Loop through the list of ssl sites
for website in $sites;
do
# Get info about the config file that describes the host
config=$(apachectl -S 2>&1 |grep "443 namevhost $website" |cut -d "(" -f 2 |cut -d ":" -f1);
if [[ $config != "" ]];
then
# Find where the config starts
start=$(apachectl -S 2>&1 |grep "443 namevhost $website" |cut -d ":" -f 2 |cut -d ")" -f 1);
# Find where the config ends
eof=$(cat $config |wc -l)
end=$(cat -n $config |sed -n "$start,$eof"p |grep "</Virtual.ost>" |sed -n '1p' |awk '{print $1}');
# Cut the host settings out of the config
sed -n "$start","$end"p $config >> extracted_hosts.conf;
echo "" >> extracted_ssl_hosts.conf;
else
echo "check $website";
fi;
done
If you change the filename extracted_host.conf to $website.conf, each site’s config will get saved into its own separate file.