How to grep a block of text? - bash

I want to delete a block of specific server from this file
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>
<VirtualHost *>
DocumentRoot "documentroot"
ServerName newserver
</VirtualHost>
So far I've used the following, but it doesn't seem to give me the proper result, but instead greps for each line of the block (of the inner grep) individually.
grep -vF "$(grep -w -B 2 -A 1 'newserver'/Applications/MAMP/conf/apache/httpd.conf)" /Applications/MAMP/conf/apache/httpd.conf;
The above results in the following:
NameVirtualHost *
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
While instead I want the following:
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>

Another one with diff and parts of your initial command:
diff <(grep -w -B 2 -A 1 'newserver' /Applications/MAMP/conf/apache/httpd.conf) \
/Applications/MAMP/conf/apache/httpd.conf |
grep -e '^> ' | sed -e 's/^> //'

awk alone:
$ awk '!/ServerName newserver/{printf "%s%s", $0, RS}' RS='</VirtualHost>' file
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>
RS defines </VirtualHost> as record separator and awk will prints those records($0) that doesn't match with ServerName newserver in it. And then print the RS(</VirtualHost>) again which is removed when we change RS to that.

$ tac vhost | awk 'NR>4' | tac
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>
This is a 'trick' to remove the last Vhost by the known numbers of lines it contains

If you want to delete an entry with ServerName newserver then use this perl one-liner:
perl -0pe 's~(?s)\s?<VirtualHost[^>]*>((?!</VirtualHost>).)*ServerName newserver.*</VirtualHost>~~' file
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>
Using a variable:
s='newserver'
perl -0pe 's~(?s)\s?<VirtualHost[^>]*>((?!</VirtualHost>).)*ServerName '"$s"'.*</VirtualHost>~~' file
RegEx Demo
Explanation:
This perl command uses a regex that matches a block starting from these 2 tags:
<VirtualHost[^>]*>
and
</VirtualHost>
and finds this pattern in between these 2 patterns:
ServerName newserver
It uses a negative lookahead pattern using (?!</VirtualHost>) that makes sure only when ServerName test comes then only match is found.

Related

Cut Apache virtual host block

I'm trying to cut certain virtual host from file which has a lot of them using bash.
Eg. in my script I would like to get virtual host which uses the_one_known2.example.com, but another time the_one_known3.example.com, namely I would like to get some part form apache config file with beforehand known URL (present in ServerName or ServerAlias) which is set in bash script as a parameter.
<VirtualHost *:80 *:${SERVER_PORT}>
ServerName test1.example.com
ServerAlias test2.example.com
ServerAlias the_one_known1.example.com
ServerAlias test3.example.com
</VirtualHost>
<VirtualHost *:80 *:${SERVER_PORT}>
ServerName test4.example.com
ServerAlias the_one_known2.example.com
ServerAlias test5.example.com
ServerAlias test6.example.com
</VirtualHost>
<VirtualHost *:80 *:${SERVER_PORT}>
ServerName the_one_known3.example.com
ServerAlias test7.example.com
ServerAlias test8.example.com
ServerAlias test9.example.com
</VirtualHost>
So I my URL variable would change to eg. the_one_known2.example.com I would get:
<VirtualHost *:80 *:${SERVER_PORT}>
ServerName test4.example.com
ServerAlias the_one_known2.example.com
ServerAlias test5.example.com
ServerAlias test6.example.com
</VirtualHost>
[EDIT]
So far I tried to find first line of a selected virtual host:
url_line=$(grep -n -m 1 "${URL}" ./apache.conf" | sed 's/\([0-9]*\).*/\1/')
vitual_host_start_line="$((app_line-1))" // this is an assumption that Virtual Host starts just one line before the first occurance of URL
echo $vitual_host_line // the place it starts
But I have a problem to find a last line of this virtual host because it is first occurence of </VirtualHost> after vitual_host_start_line
With awk:
awk -v name="the_one_known2.example.com" 'BEGIN{RS=ORS="</VirtualHost>\n"} $0~name{print; exit}' file
I assume the_one_known2.example.com is no substring of another domain in your file.
See: 8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR
With your shown samples, please try following awk code. Written and tested in GNU awk.
awk -v RS='<VirtualHost[^/]*/' -v ORS="VirtualHost>\n" 'RT~/[[:space:]]+the_one_known2\.example\.com\n/{print RT}' Input_file
Explanation: Simple explanation would be, making RS(record separator) from <VirtualHost till next / occurrence(non-greedy match). Then checking if it has [[:space:]]+the_one_known2\.example\.com\n if yes then print matched value, this will print VirtualHost> at ending of passage since its set as ORS value in program.

Bash echo multi line to end of file but dont echo in terminal

I'm writing a custom alias function to create my vhosts for me whenever i'm creating a new web project. In my function, I want to paste an entire new virtual host into my httpd-vhosts.conf file. I'm first asking for an input for the domain name and folder name to create like this
read -p 'Please enter the domain for your new site: ' domain;
read -p 'Please enter the folder name for your new site: ' folder;
and then in my function, i'm writing to my httpd-vhosts.conf file like this
echo "
<VirtualHost *:80>
ServerAdmin $domain
DocumentRoot \"/Users/sam/Development/Websites/$folder\"
ServerName $domain
ErrorLog \"/usr/local/var/log/httpd/$folder/error_log\"
CustomLog \"/usr/local/var/log/httpd/$folder/access_log\" common
</VirtualHost>" | sudo tee -a /usr/local/etc/httpd/extra/httpd-vhosts.conf;
But i've noticed this echo's in the terminal as well as in the conf file. The function works perfectly, but how do I get it to NOT echo in the terminal?
Do I have to use something other than echo to append to the file to achieve this?
Just redirect to /dev/null:
echo "
<VirtualHost *:80>
ServerAdmin $domain
DocumentRoot \"/Users/sam/Development/Websites/$folder\"
ServerName $domain
ErrorLog \"/usr/local/var/log/httpd/$folder/error_log\"
CustomLog \"/usr/local/var/log/httpd/$folder/access_log\" common
</VirtualHost>" | sudo tee -a /usr/local/etc/httpd/extra/httpd-vhosts.conf > /dev/null
This allows you to append with sudo privileges while also not showing the output on screen.
instead of tee you may consider to use >>
sudo sh -c "echo \"
<VirtualHost *:80>
ServerAdmin $domain
DocumentRoot \"/Users/sam/Development/Websites/$folder\"
ServerName $domain
ErrorLog \"/usr/local/var/log/httpd/$folder/error_log\"
CustomLog \"/usr/local/var/log/httpd/$folder/access_log\" common
</VirtualHost>\" >> test2.out"

xampp laravel blank page when using vhost windows

Trying to use xampp for my virtual host on Windows 10.
But when I open up my project in browser it's a blank page. Not an error message, just blank.
Can anyone help?
Here's my VHosts
# Virtual Hosts
#
# Required modules: mod_log_config
# If you want to maintain multiple domains/hostnames on your
# machine you can setup VirtualHost containers for them. Most configurations
# use only name-based virtual hosts so the server doesn't need to worry about
# IP addresses. This is indicated by the asterisks in the directives below.
#
# Please see the documentation at
# <URL:http://httpd.apache.org/docs/2.4/vhosts/>
# for further details before you try to setup virtual hosts.
#
# You may use the command line option '-S' to verify your virtual host
# configuration.
#
# Use name-based virtual hosting.
#
#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ##ServerName or ##ServerAlias in any <VirtualHost> block.
#
##<VirtualHost *:80>
##ServerAdmin webmaster#dummy-host.example.com
##DocumentRoot "C:/xampp/htdocs/dummy-host.example.com"
##ServerName dummy-host.example.com
##ServerAlias www.dummy-host.example.com
##ErrorLog "logs/dummy-host.example.com-error.log"
##CustomLog "logs/dummy-host.example.com-access.log" common
##</VirtualHost>
##<VirtualHost *:80>
##ServerAdmin webmaster#dummy-host2.example.com
##DocumentRoot "C:/xampp/htdocs/dummy-host2.example.com"
##ServerName dummy-host2.example.com
##ErrorLog "logs/dummy-host2.example.com-error.log"
##CustomLog "logs/dummy-host2.example.com-access.log" common
##</VirtualHost>
<VirtualHost *:3000>
DocumentRoot "C:/xampp/htdocs/"
ServerName localhost
</VirtualHost>
<VirtualHost *:3000>
DocumentRoot "C:/xampp/htdocs/projectlara2/public/"
ServerName projectlara2.test
</VirtualHost>
HERE'S MY Hosts File
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1:3000 localhost
# ::1 localhost
127.0.0.1 localhost projectlara2.test
::1 localhost projectlara2.test
Not quite sure what else I'm supposed to write here. It says I have a post that's mostly code so I should add more details but there aren't any more details. Hopefully this is enough extra writing because this is a bit annoying.
You have not provided the virtual host properly in your windows host file. You need to just change a little in host file and probably it will solve your error.
change your entry of virtual host in host file from 127.0.0.1 localhost projectlara2.test to 127.0.0.1 projectlara2.test and ::1 localhost projectlara2.test to ::1 projectlara2.test.
The problem is although you are using virtual host for the project you are declaring localhost with it. Just write the ip and domain name of virtual host, nothing else.
On your Windows10 hosts file use this only:
127.0.0.1 localhost wiki.com projectlara2.test
Then in your vhosts file you can do this:
<VirtualHost projectlara2.test:80>
ServerAdmin webmaster#dummy-host.example.com
DocumentRoot "C:/xampp/htdocs/projectlara2/public/"
ServerName projectlara2.test
ErrorLog "logs/error.log"
CustomLog "logs/access.log" common
</VirtualHost>
ServerAdmin, ErrorLog, CustomLog are optional and you can set them up with a real path if you want to, you aren't specifing the server name on your first line on your VirtualHost, when you specify it like this *: you are saying that all requests should point to the VirtualHost you are about to define, so if you want more than 1 VirtualHost you should be more specific like I showed. Hope it works! :D

Same Rightscript used multiple times on a ServerTemplate with different inputs

I have just created my first Rightscale ServerTemplate and Deployment using a bunch of Rightscripts. One of the scripts I created was to add a virtual host to apache.
#!/bin/bash -e
if [ $RS_DISTRO = ubuntu ]; then
export apache=apache2
export apache_extra_conf_dir=/etc/apache2/conf.d
elif [ $RS_DISTRO = centos ]; then
export apache=httpd
export apache_extra_conf_dir=/etc/httpd/conf.d
fi
server_name=$SERVER_NAME
echo "Adding virtual hosts to ${apache_extra_conf_dir}/vh-${server_name}.conf"
cat > $apache_extra_conf_dir/vh-${server_name}.conf <<EOF
NameVirtualHost $SITE_IP:$SITE_PORT
<VirtualHost $SITE_IP:$SITE_PORT>
ServerName $SERVER_NAME
ServerAlias $SITE_DOMAIN *.$SITE_DOMAIN
UseCanonicalName Off
ServerAdmin $ADMIN_EMAIL
DocumentRoot $APACHE_WWW_DIR
<Directory "$APACHE_WWW_DIR">
Options FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
EOF
service $apache restart
exit 0
My question is can I use the same Rightscript twice on the ServerTemplate but set different inputs for each (IP, Port, www dir and Servername)? eg.
ServerTemplate:
Execute Rightscript vhost: *:80 /www-x/ x.com
Execute Rightscript vhost: *:80 /www-y/ y.com
OR do I have to create a special Rightscript just for this server deployment that has both virtual hosts defined in the same script?
Execute Rightscript vhost: *:80 /www-x/ x.com | *:80 /www-y/ y.com
You can use the same RightScript with different inputs only if you put that script in the "Operational Scripts" section of your ServerTemplate. Then if you leave the inputs blank, you can execute that operational script with different inputs many times.
If you want that behavior in the "Boot Scripts" section, you'll have to either create a single script which handles two sets of inputs (for two vhosts) or create a clone of the RightScript with a different name and different input names.
You might consider taking a look at the Chef based tools. You can create a Chef recipe which takes an array of vhost names as input, then executes the "apache_site" resource that sets up a vhost. You can see an example in the RightScale Chef code linked below.
https://github.com/rightscale/cookbooks_public/blob/master/cookbooks/web_apache/recipes/setup_frontend_http_vhost.rb

Multiple Ruby apps on one port, RackBaseURI help

I'm trying to get two Ruby apps to work from the same port. I don't know server technology at all, so forgive my ignorance. I've tried to follow this doc:
http://www.modrails.com/documentation/Users%20guide%20Apache.html
sections 4.1 - 4.3, but I keep messing something up. I've tried to simplify a little, so here is my situation. I have two simple rackup apps here:
/Users/dan/webapps/test1
/Users/dan/webapps/test2
They each have the "config.ru" file, the public/ folder, and the tmp/ folder with "restart.txt", as directed. They both work on their own.
I have the following in my httpd.conf file:
<VirtualHost *:80>
ServerName localhost
DocumentRoot /Users/dan/webapps
<Directory /Users/dan/webapps>
Allow from all
</Directory>
RackBaseURI /test1
<Directory /Users/dan/webapps/test1>
Options -MultiViews
</Directory>
RackBaseURI /test2
<Directory /Users/dan/webapps/test2>
Options -MultiViews
</Directory>
</VirtualHost>
I start apache, and then put this in my browser: http://localhost/test1. I get:
Forbidden
You don't have permission to access /test1 on this server.
I'm not surprised it doesn't work, because I am supposed to set up a symlink but I don't know how to apply that to my setup. Here is the example from the doc:
ln -s /webapps/rackapp/public /websites/phusion/rack
Can you tell me how to set up the symlinks, and let me know if you see anything else wrong? Please give the "for dummies" answer, this stuff boggles my mind. Thanks!
To create the symlinks, try this:
ln-s /Users/dan/webapps/test1 /Users/dan/webapps/test1/public
ln-s /Users/dan/webapps/test2 /Users/dan/webapps/test2/public
However, as chris polzer mentioned, you should also check that your apache user can read from those directories.
If you don't know how to do that, then post the output of these commands:
ls -l /Users/dan/webapps/test1
ls -l /Users/dan/webapps/test2.
ps -aux | grep http
ps -aux | grep apache
You may also need to check the permissions of all parent directories. I.e. /Users, /Users/dan, and /Users/dan/webapps. See: http://www.modrails.com/documentation/Users%20guide%20Apache.html#_deploying_to_a_virtual_host_8217_s_root_2
phylae, I think you may have the paths reversed in the symbolic link. To get it working, I changed the link names for clarity:
<VirtualHost *:80>
ServerName localhost
DocumentRoot /Users/dan/webapps
<Directory /Users/dan/webapps>
Allow from all
</Directory>
RackBaseURI /test1link
<Directory /Users/dan/webapps/test1>
Options -MultiViews
</Directory>
RackBaseURI /test2link
<Directory /Users/dan/webapps/test2>
Options -MultiViews
</Directory>
</VirtualHost>
and then, the symbolic links:
ln -s /Users/dan/webapps/test1/public /Users/dan/webapps/test1link
ln -s /Users/dan/webapps/test2/public /Users/dan/webapps/test2link
Then these urls work as expected in a browser.
http://localhost/
http://localhost/test1link
http://localhost/test2link

Resources