I need to update a text file whenever my IP address changes, and then run a few commands from the shell afterwards.
Create variable LASTKNOWN = "212.171.135.53" This is the ip address we have while writing this script.
Get the current IP address. It will change on a daily basis.
Create variable CURRENT for the new IP.
Compare (as strings) CURRENT to LASTKNOWN
If they are the same, exit()
If they differ,
A. "Copy" the old config file (/etc/ipf.conf) containing LASTKNOWN IP address into /tmp B. Replace LASTKNOWN with CURRENT in the /tmp/ipf.conf file.
C. Using subprocess "mv /tmp/ipf.conf /etc/ipf.conf"
D. Using subprocess execute, "ipf -Fa -f /etc/ipf.conf"
E. Using subprocess execute, "ipnat -CF -f /etc/ipnat.conf"exit()
I know how to do steps 1 through 6. I fall down on the "file editing" part, A -> C. I can't tell what module to use or whether I should be editing the file in place. There are so many ways to do this, I can't decide on the best approach. I guess I want the most conservative one.
I know how to use subprocess, so you don't need to comment on that.
I don't want to replace entire lines; just a specific dotted quad.
Thanks!
Another way to simply edit files in place is to use the
fileinput
module:Probably the simplest way would be to open a file using f=open(filename, mode). Then, read all the lines using f.readlines() (this will return a list of strings representing the lines of the program).
You can then search these strings to find the address and replace it with the new one (using standard string replacing, regular expressions, or whatever you want).
At the end, you can write the lines back to the file using f.writelines(lines), which conveniently takes back a list of lines.
NOTE: This is not an efficient way to do this, it's just the easiest. Please
Example code:
You're trying to "atomically" update the contents of a file, and there have been many delightful flame wars on the subject. But the general pattern is:
1) Write the new file to a temp file, and make sure you flush and close.
2) Use your operating system's facilities to atomically rename the temp file to the old file.
Now, you simply can't atomically rename a file in Windows, but it sounds like you're on a unix-like system anyway. You atomically rename using os.rename().
Replace LASTKNOWN by CURRENT in /etc/ipf.conf
Replace all at once
Replace line by line
Note: "/tmp/ipf.conf" should be replaced by
tempfile.NamedTemporaryFile()
or similarNote: the code is not tested.
After checking the comments and the bit of code that you put on pastebin, here is a working solution. To begin with, the file /tmp/iiiipf.conf contains:
After running the code, the file /tmp/iiiipf.conf contains:
And here is the tested working code with my stuff merged into your pastebin code:
This bit of code will do what you need even if the IP address is used several times within the configuration file. It will also change it in comment lines.
This method does not require copying to /tmp and uses one less subprocess call when restarting the firewall and NAT.
fileinput module has very ugly API, I find beautiful module for this task - in_place, example for Python 3:
main difference from fileinput:
for example - fileinput can line by line editing only, in_pace allow read whole file to memory (if it not big) and modify it.