creating file in shell then replacing text inside - bash

I have a script where i declare variables then create a file and then replace a variable within that file, this is my example script
#!/bin/bash
DMNAME = mydomain.com
cat <<EOF > /etc/nginx/conf.d/default.conf
server_name DMNAME;
root /usr/share/nginx/html/;
index index.php index.html index.htm;
ssl_certificate /etc/letsencrypt/live/DMNAME/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/DMNAME/privkey.pem;
EOF
sed -i 's/DMNAME/mydomain.com/g' /etc/nginx/conf.d/default.conf
#
Would this be the correct way of replacing DMNAME with mydomain.com ?

#!/bin/bash
DMNAME="mydomain.com"
cat <<EOF > /etc/nginx/conf.d/default.conf
server_name $DMNAME;
root /usr/share/nginx/html/;
index index.php index.html index.htm;
ssl_certificate /etc/letsencrypt/live/$DMNAME/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$DMNAME/privkey.pem;
EOF

#Bor is right that he fills /etc/nginx/conf.d/default.conf with the correct values when creating it.
When you want to use default.conf more than once, you shouldn't let sed change the file with the -i option, but redirect the results to the file you want.
# Answer: do not use this here: DMNAME = mydomain.com
cat <<EOF > /etc/nginx/conf.d/default.conf
server_name DMNAME;
root /usr/share/nginx/html/;
index index.php index.html index.htm;
ssl_certificate /etc/letsencrypt/live/DMNAME/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/DMNAME/privkey.pem;
EOF
# And now DMNAME="mydomain.com" (without spaces, quotes are optional here).
# or for different domains
confpath="/etc/nginx/conf.d"
for domain in mydomain.com yourdomain.com hisdomain.com; do
sed "s/DMNAME/${domain}/g" "${confpath}"/default.conf > "${confpath}"/${domain%.*}.conf
done

Related

How to process or excape variables inside of EOF to write file content?

This is how I create a file (nginx.conf) via shell.
As there are $ characters in the filecontent I'm using EOF.
if [ $type == "nginx" ]; then
cat > ${path}/nginx.conf <<'EOF'
server {
listen 3000;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
include /etc/nginx/extra-conf.d/*.conf;
}
EOF
fi
Now I have to use a dynamic port value, so instead of listen 3000 I need to use listen $port.
But this won't work, as in the content there is also $uri, which should be handled as text, not as a variable.
Using only the delimiter itself, either all parameters are expanded or none. You'll have to allow expansion, but escape the dollar signs for $uri to inhibit their expansion.
if [ "$type" = "nginx" ]; then
cat > "${path}/nginx.conf" <<EOF
server {
listen $port;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files \$uri \$uri/ /index.html = 404;
}
include /etc/nginx/extra-conf.d/*.conf;
}
EOF
fi
The here document behaves like a double-quoted string:
$ foo=bar
$ echo "$foo"
bar
$ echo "\$foo"
$foo

Shell Script To Automate Nginx Blocks

I'm trying to automate nginx setup through the script
Command - SECRET_KEY='xxxx' HTTP='$http_update' AMCU_HOST='$host' AMCU_RURI='$redirect_uri' sh ./script.sh domain.com port username
In the server block file, I want HTTP='$http_update' but it replaces it and just leave blank ''. Same for AMCU_HOST='$host' and AMCU_RURI='$redirect_uri'. Tried without attributes in command but same happens again...leaves '' as script thinks it as $ attr.
script.sh
#!/bin/bash
domain=$1
port=$2
user=$3
block="/etc/nginx/sites-available/$domain"
ssh="/home/$user/.ssh/authorized_keys"
#Create User
echo "▶ Creating User"
sudo useradd $user
#User mkdir
echo "▶ Updating home dir"
sudo mkdir /home/$user
#Create .ssh/authkeys
echo "▶ Updating SSH dir"
cd /home/$user && mkdir .ssh/
#Create the SSH Auth file:
echo "▶ Updating SSH AuthKey"
sudo tee $ssh > /dev/null <<EOF
$SECRET_KEY
EOF
#Create the Nginx server block file:
echo "▶ Updating NGINX Server Block"
sudo tee $block > /dev/null <<EOF
server {
listen 80;
server_name $domain;
return 301 https://$domain$AMCU_RURI;
}
server {
#Secure HTTP (HTTPS)
listen 443 ssl;
server_name $domain;
error_page 500 502 503 504 /500.html;
location /500.html {
root /var/www/html;
internal;
}
ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
proxy_pass http://localhost:$port;
proxy_http_version 1.1;
proxy_set_header Upgrade $HTTP;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $AMCU_HOST;
proxy_cache_bypass $HTTP;
}
}
EOF
#Link to make it available
echo "▶ Linking Server Blocks"
sudo ln -s $block /etc/nginx/sites-enabled/
#Test configuration and reload if successful
echo "▶ Reloading Server"
sudo nginx -t && sudo service nginx reload

How to append multi-lines to file in a dockerfile? [duplicate]

This question already has answers here:
launch a CAT command unix into Dockerfile
(7 answers)
Closed 7 months ago.
I have a dockerfile and can't seem to be able to embed the nginx configuration file to it, so that it can be appended to /etc/nginx/nginx.conf.
I tried the following formats:
RUN cat <<EOT >> /etc/nginx/nginx.conf
user www;
worker_processes auto; # it will be determinate automatically by the number of core
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid; # it permit you to use /etc/init.d/nginx reload|restart|stop|start
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
access_log /var/log/nginx/access.log;
keepalive_timeout 3000;
server {
listen 80;
root /usr/local/www;
index index.html index.htm;
server_name localhost;
client_max_body_size 32m;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/lib/nginx/html;
}
}
}
EOT
and
RUN echo $
'user www; \n
worker_processes auto; # it will be determinate automatically by the number of core \n
error_log /var/log/nginx/error.log warn; \n
pid /var/run/nginx.pid; # it permit you to use /etc/init.d/nginx reload|restart|stop|start \n
events { \n
worker_connections 1024; \n
} \n
http { \n
include /etc/nginx/mime.types; \n
default_type application/octet-stream; \n
sendfile on; \n
access_log /var/log/nginx/access.log; \n
keepalive_timeout 3000; \n
server { \n
listen 80; \n
root /usr/local/www; \n
index index.html index.htm; \n
server_name localhost; \n
client_max_body_size 32m; \n
error_page 500 502 503 504 /50x.html; \n
location = /50x.html { \n
root /var/lib/nginx/html; \n
} \n
} \n
}'
> /etc/nginx/nginx.conf
However with either of the two examples I get the following error, which kinda looks like docker is trying to treat the nginx config file as its own variables:
Sending build context to Docker daemon 33.28 kB
Error response from daemon: Unknown instruction: WORKER_PROCESSES
Docker version is 1.13.1, build 07f3374/1.13.1 and the distro I am using is CentOS Atomic Host 7.1902, while docker base image is alpinelinux.
Thanks
That should do the trick:
RUN echo $'first line \n\
second line \n\
third line' > /etc/nginx/nginx.conf
Basically it's wrapped in a $'' and uses \n\ for new lines.
I was looking to create & append lines to my .npmrc to install private packages. The only syntax that worked for me was:
RUN echo #myscope:registry=https://gitlab.com/api/v4/packages/npm/ > .npmrc \
&& echo //gitlab.com/api/v4/packages/npm/:_authToken=${MY_TOKEN} >> .npmrc \
&& echo strict-ssl=false >> .npmrc

Nginx Redirection Loop

I'm very new to NGINX (and bash) and I'm attempting to write a bash script to automate the creation of a new site (so adding a server block) to a webserver. However for some reason my script appears to be putting me into a redirect loop. Any ideas?
cd /var/www/
git clone git#bitbucket.org:wardy484/portfolio.git
mv portfolio kimward.co.uk
sudo chmod -R 755 kimward.co.uk
FILE="/etc/nginx/sites-available/kimward.co.uk"
/bin/cat <<EOM >$FILE
server {
listen 80;
listen [::]:80;
root /var/www/kimward.co.uk/public;
index index.php index.html index.htm;
server_name kimward.co.uk www.kimward.co.uk;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
include fastcgi_params;
}
}
EOM
sudo nano /etc/nginx/sites-available/kimward.co.uk
sudo ln -s /etc/nginx/sites-available/kimward.co.uk /etc/nginx/sites-enabled/
sudo service nginx restart
cd /var/www/kimward.co.uk
composer install
composer update
$uri, $url, $query_string, etc. are nginx variables and needs to be escaped or they will be expanded by the shell:
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
Same might be the case with other special characters. Instead of having to escape them all you should use << 'EOM' which will treat the here document as a single quoted string.
file="/etc/nginx/sites-available/kimward.co.uk"
/bin/cat <<'EOM' >"$file"
server {
listen 80;
listen [::]:80;
...
...
EOM
I also lower cased $FILE since all uppercase names are reserved for environment variables.

How to remove multiple lines from file in bash?

I am adding several lines to a file like this:
echo "server {
listen 80;
server_name ${brand}.mydomain.com;
root /srv/www/clients/${brand}/soon;
}" >> default
The result is like this (brand is passed via parameter) :
server {
listen 80;
server_name cola.mydoman.com;
root /srv/www/clients/cola/soon;
}
The question is how to remove this specifically if this file contains lots of similar other values. Is it possible to do this with sed, awk or something else?

Resources