2

I use printf to setup my Nginx settings, and it works fine, but it's awkward to read and alter; is there a better way to improve readability?

config.vm.provision "shell", inline: <<-SHELL

    sudo rm /etc/nginx/sites-enabled/default

    sudo printf '%s\n' 'server {' 'root /home/vagrant/web;' 'index index.php index.html index.htm;' 'location / {' 'try_files $uri $uri/ /index.php?$args ;' '}' 'location ~ \.php$ {' 'fastcgi_split_path_info ^(.+\.php)(/.+)$;' 'fastcgi_pass unix:/var/run/php5-fpm.sock;' 'fastcgi_index index.php;' 'include fastcgi_params;' '}' '}' >> /etc/nginx/sites-enabled/default

    sudo service nginx start

SHELL
Mike Thrussell
  • 4,175
  • 8
  • 43
  • 59
  • Assuming this is legal in a vagrantfile you could just use a single single-quoted string as the argument to `printf` and use literal newlines in the string. – Etan Reisner Apr 27 '15 at 19:42
  • 2
    `sudo printf` only raises permissions of the `printf` command, which is run only *after* the output file is opened, meaning it doesn't give you any elevated privileges for opening the output file, so the `sudo` given here has no benefit over the way your Vagrantfile would work if you left it out. – Charles Duffy Apr 27 '15 at 21:54

1 Answers1

4

Assuming that there is Bash on your guest machine, you could try and use nested bash here documents. There is no guarantee that will work with Vagrantfile but it's worth a shot anyway.

config.vm.provision "shell", inline: <<-SHELL

    sudo /bin/bash << 'SCRIPT'
        rm /etc/nginx/sites-enabled/default;

        cat << 'EOF' >> /etc/nginx/sites-enabled/default
            %s\n

            server {
                root /home/vagrant/web;
                index index.php index.html index.htm;

                location / {
                    try_files $uri $uri/ /index.php?$args ;
                }

                location ~ \.php$ {
                    fastcgi_split_path_info ^(.+\.php)(/.+)$;
                    fastcgi_pass unix:/var/run/php5-fpm.sock;
                    fastcgi_index index.php;
                    include fastcgi_params;
                }
            }
EOF
        service nginx start
SCRIPT
SHELL

Note that EOF, SCRIPT and SHELL must be placed in the very beginning of the line. There must not be any tabs or whitespaces in front of these words.

Ivan Tsirulev
  • 2,751
  • 1
  • 19
  • 19
  • 1
    The only obvious problem here is that you aren't quoting your heredoc sigils, so their parameter expansions are evaluated by the outer shell. `<<'EOF'` or `<<\EOF` would emit content literally, rather than trying to evaluate `$uri` based on shell variables in the shell evaluating the heredoc. – Charles Duffy Apr 27 '15 at 21:56
  • ...by contrast, `<<-SHELL` is Ruby syntax in the outer piece of a Vagrantfile, not shell, so there's no need to quote the sigil there. – Charles Duffy Apr 27 '15 at 21:57
  • @CharlesDuffy Yes, you are right. Thank you for noticing this mistake. I have corrected my answer. – Ivan Tsirulev Apr 27 '15 at 22:05