Bash substitution cut off end of string - bash

I have bash script which should replace some placeholders in text template by users input.
#!/bin/bash
# Run this script as bash command like: bash create-apache-site.sh
read -p 'Write url without www and http prefixes: ' url
template=$(</etc/apache2/sites-available/000-default.conf)
template2=("${template/1*****/$url}")
echo "$template2" > /home/Camo/template.txt
Template file is multi-line string with placeholders (1*****, 2*****, ...) which looks like
<VirtualHost *:80>
ServerAdmin xxxx.xxxxx#gmail.com
ServerName 1*****
ErrorLog ${APACHE_LOG_DIR}/www/2*****/error.log
CustomLog ${APACHE_LOG_DIR}/www/3*****/access.log combined
DocumentRoot /var/www/html/4*****
<Directory /var/www/html/5*****/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
Require all granted
</Directory>
RewriteEngine on
RewriteCond %{SERVER_NAME} = 6*****
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
But the result of this script is this damaged file
<VirtualHost *:80>
ServerAdmin xxxx.xxxxx#gmail.com
ServerName ooooooooooooooo.com
As you can see substitution cut off the end of the string. Can somebody tell me please what is wrong with it? Thanks a lot.

You have to escape your * for the replace to work.
Maybe a better way is to not use * as your placeholder? But I leave that up to you.
Try this:
(I also made the replacement global so that you can reuse the same placeholder several times within the file)
#!/bin/bash
# Run this script as bash command like: bash create-apache-site.sh
read -p 'Write url without www and http prefixes: ' url
template=$(</etc/apache2/sites-available/000-default.conf)
template2=("${template//1\*\*\*\*\*/$url}")
echo "$template2" > /home/Camo/template.txt

Related

Using wildcard * on include of apache not working on OSX

Couldn't find any info about this.
tl;dr
Can't manage to include all conf files of a directory with * wildcard as Include /path/to/directory/*.conf
Extended explanation
I have the contents
$ cd /private/etc/apache2
$ tree vhosts
. vhosts
`-- test.conf
$ cat vhosts/test.conf
<VirtualHost *:80>
DocumentRoot "/Users/ml/web/"
ServerName localhost
</VirtualHost>
$
So if I append into /private/etc/apache2/httpd.conf:
Include /private/etc/apache2/vhosts/test.conf
It works as expected, but if I use *.confinstead like:
Include /private/etc/apache2/vhosts/test.conf
It wont work.
This exists in an example (in httpd.conf), shouldn't this work? Or might be something I'm doing it wrong?
On Apache 2.4 use IncludeOptional instead of Include when using wildcards. More here: https://www.digitalocean.com/community/tutorials/migrating-your-apache-configuration-from-2-2-to-2-4-syntax

Writing common file with replacements in bash

I am writing a script to setup new projects on my computer,
One part I am wanting to do is have it automatically setup the virtual hosts for me.
The file itself is quite simple
the file should be called <project>.testfox.dev.conf and should contain
<VirtualHost *:80>
DocumentRoot "/var/www/work/<project>"
ServerName <project>.testfox.dev
<Directory "/var/www/work/<project>">
allow from all
Options +Indexes
</Directory>
ErrorLog /var/log/apache2/<project>.error.log
LogLevel error
TransferLog /var/log/apache2/<project>.access.log
</VirtualHost>
What I wonder is, should I have that code in my script and write it out line by line to the file, or should I have a dummy file in the sites-available folder that I copy and then search a replace a placeholder?
The most flexible way would be to have it as a template (either as a separate file, or a HEREDOC), writing it line-by-line would make it very hard to modify in future.
The HEREDOC approach would be easier to implement, as you can use variable interpolation:
cat >$PROJECT.testfox.dev.conf <<EOF
<VirtualHost *:80>
DocumentRoot "/var/www/work/$PROJECT"
ServerName $PROJECT.testfox.dev
<Directory "/var/www/work/$PROJECT">
allow from all
Options +Indexes
</Directory>
ErrorLog /var/log/apache2/$PROJECT.error.log
LogLevel error
TransferLog /var/log/apache2/$PROJECT.access.log
</VirtualHost>
EOF
Both are viable approaches.
Using it as a template makes it easier and more readable, if you want to modify it. But keeping it in a bash script as a here document works as well.
In the end, it depends on what your preferences are.

combining mod_rewrite and vhost_dbd_module

I'm trying to give users a static files folder served from inside their chroot. The following code works under other conditions (basically without the inclusion of the DBDocRoot directive) but just doesn't do what is expected. Is mod_vhost_dbd simply not compatible with mod_rewrite? It partially works in that the request hits the correct python script which then does some other stuff and launches a wsgi app.
With this code nothing is logged in rewrite.log. If you comment out the DBDocRoot directive line stuff is logged but of course the rewrite rule doesn't work because ${ENV:username} is the empty string. The query work perfectly well when run from a mysql console.
LoadModule vhost_dbd_module /usr/lib/apache2/modules/mod_vhost_dbd.so
DBDExptime 5
<VirtualHost *:80>
ServerAlias *
RewriteEngine On
RewriteLog "/var/log/apache2/rewrite.log"
RewriteLogLevel 9
DBDriver mysql
DBDParams host=amysqlhost,user=abdbuser,pass=private,dbname=adbname
DBDocRoot "SELECT concat('/mnt/user_storage/webscripts/', username, '/user_script.py'), username from user, userdomain where user.id = userdomain.user_id and userdomain.domain_name = %s" HOSTNAME
RewriteCond /mnt/user_storage/homedirs/%{ENV:username}/var/www/static%{REQUEST_URI} -f
RewriteRule ^/(.*) /mnt/user_storage/homedirs/%{ENV:username}/var/www/static/$1 [L]
</VirtualHost>
Has anyone else successfully used this module to set an environment variable? The notes on the mod_vhost_dbd wiki say that it can be done.

turn off mod_rewrite for subdirectory

In httpd.conf, I have a rewrite rule in the webroot
first, I turn off mod_rewrite in the subdirectory
<directory /home/xxxx/public_html/subdir>
RewriteEngine off
</directory>
then turn on where needed
<directory /home/xxxx/public_html>
RewriteEngine On
# bunch of rewrite rules
</directory>
But rewrite engine remains on in subdir. I've done logging with RewriteLog 3 and see it processing files in subdir.
I've tried moving the subdir below the main directory section in httpd.conf but still it processes subdir files.
I know I could match and exclude the subdir in my main rules, but I'm trying to avoid the processing of that directory at all for speed.
Any ideas why or how to turn off mod_rewrite for a subdirectory?

Bash: how to check and insert a string within a block in a file

Having a block in http.conf file like:
<IfModule mime_module>
...
</IfModule>
Assuming using bash, how can I check if the following line
AddHandler application/x-httpd-php .php
has been already added within the previous block,
and, if not, how can I add it at its bottom resulting in
<IfModule mime_module>
...
AddHandler application/x-httpd-php .php
</IfModule>
This block is just in the middle of the file:
the file content doesn't start or end with this block.
EDITED:
To make this harder, I realized I need a further check too: sorry to have missed it in my question. If the above line is already present within the mentioned block as a commented line as
# AddHandler application/x-httpd-php .php
(the char # might be the first char of the line or it might have some spaced before, as it might have or not some spaces after before the char A of AddHandler), I simply need to uncomment it, otherwise I have proceed to add it as described.
awk '
/mime_module/{
flag=1
}
flag && /x-httpd-php/{
has=1
}
flag && /<\/IfModule>/{
flag = 0
if(!has)
print "AddHandler application/x-httpd-php .php"
}
1' input.conf
This might work for you:
sed -i ':a;$!N;/^<IfModule mime_module>.*<\/IfModule>/{s/# *\(AddHandler application\/x-httpd-php \.php\)/\1/;/AddHandler application\/x-httpd-php \.php/!s/.*\n/&\n AddHandler application\/x-httpd-php .php\n/;p;d};/^<IfModule mime_module>/ba;P;D' input.conf
The following will replace anything inside the block "IfModule - /IfModule" with your text "AddHandler application/x-httpd-php .php". So regardless if the comment (#) is found or if nothing is found the block will have the correct information.
Also it is IMPORTANT to note that this is an inline edit. The file you are wanting changed will be changed immediately upon running this script with NO BACKUP MADE. PRIOR TO TESTING ANYTHING PLEASE BACKUP YOUR FILE.
sed -i '/<\/IfModule>/,/<IfModule>/!s/ \.\.\..*/ \.\.\.\n AddHandler application\/x-httpd-php .php/g' /yourfile
If you are working on OS X, you may want to try the following script instead
#!/bin/bash
CR="$(printf '\r')"
sed -i '' "/<\/IfModule>/,/<IfModule>/!s/ \.\.\..*/ \.\.\.${CR} AddHandler application\/x-httpd-php .php/g" /yourfile
Example of Starting file:
<IfModule>
...
</IfModule>
<NOTHING TO CHANGE>
...
</NOTHING TO CHANGE>
<IfModule>
...
# AddHandler application/x-httpd-php .php
</IfModule>
<NO CHANGE>
...
NO CHANGE
</NO CHANGE>
Results:
<IfModule>
...
AddHandler application/x-httpd-php .php
</IfModule>
<NOTHING TO CHANGE>
...
</NOTHING TO CHANGE>
<IfModule>
...
AddHandler application/x-httpd-php .php
</IfModule>
<NO CHANGE>
...
NO CHANGE
</NO CHANGE>

Resources