4

Here is a problem which is annoying me during these last two hours. I have a template file with multiple lines and in some lines some words have to be changed by some others. Here is how my template looks like:

subnet {{ MY_SUBNET }} netmask {{ MY_NETMASK }} {}

subnet {{ MY_SUBNET }} netmask {{ MY_NETMASK }}
{
option domain-name-servers {{ MY_DOMAIN_IP }}; 
option domain-name {{ MY_DOMAIN_NAME }}; 
option routers {{ MY_GATEWAY }}; 
option broadcast-address {{ MY_BROADCAST }};

Here is the code I am using:

f = open(DHCPD_PATH, 'w')
g = open(TEMPLATE_PATH, 'r')
patterns = { 
   '{{ MAC_ADDRESS }}'     : mac,
   '{{ IP_ADDRESS }}'      : ip, 
   '{{ MY_IP }}'           : MY_IP,
   '{{ MY_DOMAIN_IP }}'    : MY_DOMAIN_IP,
   '{{ MY_DOMAIN_NAME }}'  : MY_DOMAIN_NAME,
   '{{ MY_NETMASK }}'      : MY_NETMASK,
   '{{ MY_GATEWAY }}'      : MY_GATEWAY,
   '{{ MY_SUBNET }}'       : MY_SUBNET,
   '{{ MY_BROADCAST }}'    : MY_BROADCAST,
}   
content = g.read()
for i,j in patterns.iteritems():
   content = content.replace(i,j)
f.write(content)
f.close()
g.close()

Here is the file I get:

subnet 192.168.10.0 netmask {{ MY_NETMASK }} {}

subnet 192.168.10.0 netmask 255.255.255.0
{
  option domain-name-servers 192.168.10.10;
  option domain-name "localnet.lan";
  option routers 192.168.10.1;
  option broadcast-address 192.168.10.255;
  default-lease-time 600;
  max-lease-time 7200;
  filename "pxelinux.0";
  next-server 192.168.10.3;

I can't understand why is this {{ MY_NETMASK }} remaining whereas one of it has been correctly replaced and every others template-patterns get also correctly replaced.

Can anyone give me a hint on this one? Or at least explain me how to correct it?

Many thanks

2
  • 6
    Try to add print i, content.count(i) as the first line within your for loop and see what numbers it returns. Probably some encoding problem with spaces? Commented Sep 7, 2012 at 12:44
  • I tried a self-contained version of this (using a template defined in the script rather than reading it from a file), and it worked fine--both occurrences of '{{ MY_NETMASK }}' were replaced. Commented Sep 7, 2012 at 13:01

3 Answers 3

8

@eumiro guessed right: one of your spaces isn't a space.

>>> repr('subnet {{ MY_SUBNET }} netmask {{ MY_NETMASK }} {}')
"'subnet {{ MY_SUBNET }} netmask {{ MY_NETMASK\\xc2\\xa0}} {}'"
                                              ^^^^^^^^^^

Looks like a non-breaking space.

Sign up to request clarification or add additional context in comments.

Comments

3

Thank you SO much!!

To provide a more complete answer (although yours were clear enough to solve my problem) I would like to provide the vim configuration which would have spared my the pain:

provides different colors for spaces and tabulations:

:set syntax=whitespace

This line in the ~/.vimrc configuration file prints most of invisible characters if you use the :list command once your file is opened (:list! to go back to normal view):

set listchars=nbsp:¤,tab:>-,trail:¤,extends:>,precedes:<,eol:¶,trail:· 

Thanks again

Comments

2

Aside from 'iffy' characters that others have pointed out...

It may be overkill but - I would be tempted to just install the jinja2 templating library, give it TEMPLATE_PATH (either as a string, or as part of an environment or a file), then issue .render with your PATTERNS, which would become:

PATTERNS = {
    'MAC_ADDRESS': '121422242424',
    # etc...
}

The replacements will also be done all at once, rather than iteratively searched/replaced. You could also put in the template reasonable default values, ie: option something {{ MY_IP|default('127.0.0.1') }}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.