Systems management using SSH for my school I wrote this script in order to generate a hosts.txt file with the IP addresses of the laptops in my school.

Each laptop is assigned a number, and their IP addresses are assigned to them with the template "192.168.0.x". X being the computer's number + 10. All these computers are running Arch Linux with XFCE4, custom tailored to aid in education. Each laptop is setup with SSH and the Teacher, (me), has the ability to ssh into any machine and execute any command I deem necessary.

Up until recently, I would SSH into the machines individually and install programs one-by-one. Now I use a program called PSSH (Parallel SSH) to connect to certain machines simultaneously and perform my commands. I only find one issue with this arrangement, all the IP addresses are stored in a file called, you guessed it, hosts.txt.

Now, as you can imagine, this gets quite cumbersome when dealing with 70 different addresses, and I would rather not have to type all the addresses by hand. So I made this script to generate a hosts file based off the computer numbers I choose. Selecting all the machines is now as easy as typing 'all'.

addresses = []
nums = []
run = True

def rem_dupl(seq):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if not (x in seen or seen_add(x))]

while run:
    x = str(input("Computer numbers: "))

    if x == 'done':
        run = False
    elif x == 'all':
        nums = [x for x in range(1, 70)]
        run = False
    elif int(x) &gt; 0 and int(x) &lt; 70:
        nums.append(x)
    else:
        print "Out of range"
else:
    nums_finished = rem_dupl(nums)

    for i in nums_finished:
        addresses.append("192.168.0." + str((int(i) + 10)))

    temp = open('hosts', 'w').close()

    file = open('hosts.txt', 'w')
    for item in addresses:
        print&gt;&gt;file, item

   file.close


Any thoughts, constructive criticism, apparent issues, or redundancies?
As suggested in the comments, I would strongly suggest looking at a proper configuration management tool such as Ansible or Puppet (both free) instead of rolling your own. That will probably save you a lot of time, once you’ve done the initial ramp-up.



Here are some comments on the code presented:


There aren’t any comments or documentation. It’s hard to tell if this script is behaving correctly, because it’s not written anywhere. (Although the description on the question is good, it would be better if it was embedded in the script itself.)
Use full names in variables; don’t skimp out with abbreviations. It makes the code much easier to read, and characters are cheap. For example: remove_duplicates instead of rem_dupl.

Speaking of that function, here’s a cleaner way to write it:

def remove_duplicates(sequence):
    return list(set(sequence))



In the while run: loop, rather than having the sentinel variable run, it would be nicer to use break statements to get out of the loop. Something like:

while True:
    x = ...
    if x == 'done':
        break
    elif x == 'all':
        ...
        break
    else:
        ...




This is one less variable to understand and track (for the human reading your code, that is!)
In Python 2, range() already returns a list, so

nums = [x for x in range(1, 70)]




can be reduced to

nums = range(1, 70)




I suspect you probably meant

nums = [str(x) for x in range(1, 70)]




because then nums is always a list of strings, however it gets populated.
Rather than creating addresses as an empty list and populating it one-by-one, you could use a list comprehension:

addresses = ["192.168.0." + str((int(i) + 10)) for i in set(nums)]




Note that in this case, we can just deduplicate with set() – we don’t even need to recast to a list to put it in our list comprehension.
It’s not clear what the temp variable is being used for, as we never seem to do anything with the hosts file.
Rather than using the f = open(path); ...; f.close() paradigm, it’s better to use the with statement like so:

with open('hosts.txt', 'w') as f:
    f.write('\n'.join(addresses))




This ensures that the file will always be closed correctly, even if something goes wrong while you’re trying to write to it.

(For example, your file.close is missing the parentheses to actually call the close() method, so this file will never be closed.)

Note also that it’s generally considered bad practice to use a builtin as a variable name. This can be a source of fun and weird bugs, so avoid it unless absolutely necessary.




And an ancillary thought:


As presented, the hosts will be written in the order supplied. Would it be better to sort the output, so that you can easily skim the list and spot missing entries? Not a must, just an idea.