Python Syntax Truncate Error - python

I'm trying to set up a script that re-writes the interfaces file and eventually it will change the ip address to static, but when I run it I get an error the line that reads ' new_location_interfaces.truncate()' and it says that 'str' object has no attribute truncate.
from sys import argv
from os.path import exists
import os
script_name = argv
print "You are currently running %s" % script_name
print "Version: 0.1"
print """Desciption: This script will change the IP address of the
Raspberry Pi from dynamic to static.
"""
print "If you don\'t want to continue, hit CTRL-C (^C)."
print "If you do want that, hit RETURN"
raw_input("?")
# Main code block
text_to_copy = """
auto lo\n
iface lo inet loopback
iface etho inet dhcp\n
allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
"""
if exists("/etc/network/interfaces"):
print "\nFile exists."
interfaces_file = open("/etc/network/interfaces", 'w')
print "Truncating/erasing contents . ."
interfaces_file.truncate()
print "Writing contents . ."
interfaces_file.write(text_to_copy)
interfaces_file.close()
else:
print "\nCould not find the \'interfaces\' file."
print "Please specify the location:",
new_location_interfaces = raw_input()
open(new_location_interfaces, 'w')
print "Truncating/erasing contents . ."
new_location_interfaces.truncate()
print "Writing contents . ."
new_location_interfaces.write(text_to_copy)
new_location_interfaces.close()
I am very new to python and my code is probably terrible but any help would be appreciated.

new_location_interfaces is not a file object. It is a string, the result of the raw_input() call:
new_location_interfaces = raw_input()
The next line, the open() call, is not assigned to anything:
open(new_location_interfaces, 'w')
Perhaps you wanted to truncate that object?
For example:
new_location_interfaces = raw_input()
fh = open(new_location_interfaces, 'w')
print "Truncating/erasing contents . ."
fh.truncate()
print "Writing contents . ."
fh.write(text_to_copy)
fh.close()
However, opening a file for writing (mode set to w) already truncates the file, your .truncate() calls are entirely redundant.

Try indenting the spaces, here the errors occur because of the randomized mistake also try the for x in c:
print c

Related

Python3 inconsistent output inside open function and for loop

This is the code. Somehow the output is not consistent. There is a new line for the first 2 lines in ip.txt while the third is working as expected.
code.py
import subprocess
with open('ip.txt') as f:
for IPAddr in f:
ping = subprocess.Popen(['ping','-c','1',IPAddr],stdout=f).wait()
if ping == 0:
print(f'{IPAddr} is up')
else:
print(f'{IPAddr} is down')
ip.txt
127.0.0.1
10.0.0.1
127.0.0.1
Output
user#linux:~$ python 01.py
127.0.0.1
is up
10.0.0.1
is down
127.0.0.1 is up
user#linux:~$
Desired Output
user#linux:~$ python code.py
127.0.0.1 is up
10.0.0.1 is down
127.0.0.1 is up
user#linux:~$
What's wrong with this code and how to fix it?
Update
The following solutions work! Many thanks
IPAddr = IPAddr.replace('\n','')
IPAddr = IPAddr.rstrip("\n")
IPAddr = IPAddr.strip()
You're including the newline characters from your file in your print.
Remove the \n like this:
import subprocess
with open('ip.txt') as f:
for IPAddr in f:
IPAddr = IPAddr.replace('\n', '') # Remove the newline
ping = subprocess.Popen(['ping','-c','1',IPAddr],stdout=f).wait()
if ping == 0:
print(f'{IPAddr} is up')
else:
print(f'{IPAddr} is down')
Or if you want to do it more broadly, you can remove all whitespace by using:
IPAddr = IPAddr.strip()
Or if you want to be super duper efficient, just strip the \n from the right:
IPAddr = IPAddr.rstrip("\n")
When iterating over a file line by line, each line ends with the newline marker ("\n"), so what you pass to print() is actually "127.0.0.1\n is up", not "127.0.0.1 is up".
The solution is quite simple: remove the newline:
for IPAddr in f:
IPAddr = IPAddr.rstrip("\n")
# etc
Note that since external inputs (files, user inputs etc) are totally unreliable, you would be better stripping all whitespaces from the line, check it's not empty (it's common to have empty lines in text files, specially at the end) and then skip that line (with a continue statement), and if not empty you probably want to validate the value is a valid IP address (and if not skip it too)...

Executing Code in Python Web

im creating a webpage that will show me the SSID's available in my Network
For this I have use this code:
nm-tool | grep "Infra" | cut -d " " -f5 > /home/nunukene/SSID3.txt
Im saving this into a file called SSID3, to later open it using the open() , read() and str.split
My problem is that the code I want to execute in the page, wont get executed, the file SSID3.txt wont be created
This is my website code so far:
#!/usr/bin/python
import os
import subprocess
import cgitb
cgitb.enable()
a=os.system("""nm-tool | grep "Infra" | cut -d " " -f5 > /home/nunukene/SSID3.txt""")
#SSIDStr = subprocess.check_output('nm-tool | grep "Infra" | cut -d " " -f5-6', shell=True)
#SSIDArray = str.split(SSIDStr)
ID = subprocess.check_output('ls', shell=True)
a='devilman'
print "Content-type:text/html\r\n\r\n"
print "<!DOCTYPE html>"
print "<html>"
print "<title> Not Hacking lol</title>"
print "<body>"
print "<h1> Join %s One of this networks <h1>" %(a)
print "</body>"
print "</html>"
I dont know how to get this process working before the rest!
I highly suggest using the logging module to help you diagnose where your problem is.
a reason your subprocess call didn't work is you would need to make a list out of all of the arguments to the command.
SSIDStr = subprocess.check_output(['nm-tool','|','grep','"Infra"','|','cut','-d','" "','-f5'])
(I'm not sure if you have to escape the double-quotes in this string)
using the subprocess call this way avoids using the text file and it's permission problems that the web server user may be experiencing writing files.
you were re-writing the "a" variable and you weren't using the text file in the output.
and I hope the cgitb.enable() line wasn't the problem. Haven't seen that before. Have you thought of using Flask?
If you are using python 3 then the print statements need to be functions.

python - print output

I have created this below script and it works fine. But the output is not friendly (see below). I want the first line to display only the hostname and IP and remove (,'[], please suggest
('testhostname', [], ['10.10.10.10'])
cannot resolve hostname: 10.10.10.11
import socket
pfile = open ('C:\\Python27\\scripts\\test.txt')
while True:
IP = pfile.readline()
if not IP:
break
try:
host = socket.gethostbyaddr(IP.rstrip())
print host
except socket.herror, err:
print "cannot resolve hostname: ", IP
pfile.close()
Rather than printing all of the host tuple that is returned by gethostbyaddr, I suggest unpacking into separate variables that you can then print as you see fit:
hostname, alias_list, ip_addr_list = gethostbyaddr(IP.rstrip())
print hostname, ip_addr_list # or ip_addr_list[0] if you only want the one IP
If you want more control over the formatting, I suggest using the str.format method:
print "hostname: {}, IP(s): {}".format(hostname, ", ".join(ip_addr_list))
Also, a few other code suggestions (not directly related to your main question):
Use a with statement rather than manually opening and closing your file.
Iterate on the file object directly (with for IP in pfile:), rather than using while True: and calling pfile.readline() each time through.
Use the syntax except socek.herror as err rather than the older form with commas (which is deprecated in Python 2 and no longer exists in Python 3).

Python program to connect to console via telnetlib

Hi I am a tcl person trying to do a day to day activity in Python in order to get familiarity with a new language and to compare Python with tcl. No one wants tcl programs anymore :)
Ok , So I have come with a code to automate this typical activity I would do to clear a console line .
$ telnet 172.28.247.240
Trying 172.28.247.240...
Escape character is '^]'.
User Access Verification
Password:
labc-f18-ts>en
Password:
labc-f18-ts#clear line 66
[confirm]
[OK]
My Code looks like this:
import getpass
import sys
import telnetlib
a_tuple = [ ('172.28.247.240' , 66)]
HOST = j[0]
user = "admin"
password = "1234"
tn = telnetlib.Telnet(HOST)
tn.read_until("login: ")
tn.write(user + "\n")
if password:
tn.read_until("Password: ")
tn.write(password + "\n")
tn.read_until("labc-f18-ts>")
tn.write ("en" +"\n")
tn.read_until("labc-f18-ts#")
tn.write("clear line %d" %j[1])
tn.write("exit\n")
sess_op = tn.read_all()
print sess_op
But I dont seem to get any output and dont know if it actually cleared the lines - there is no output whatsoever. Please help.
Also is there anything like pexpect that I should be working with rather what I have above?
import telnetlib
# ...
a_tuple = [('172.28.247.240', 66)]
HOST = a_tuple[0] # do you mean to use 'a_tuple' instead of 'j'?
# ...
tn = telnetlib.Telnet(HOST[0], HOST[1]) # <-- pass the port, I don't think this accepts tuples of hostname/ip and port
# ...
Should part of your code looks like above instead?
Also, I would normally use carriage return (\r) instead of new line (\n) when sending commands. Some host are picky about this.

reading output from pexpect sendline

I have pexpect working, but I am having problems printing the output back from it. In my test script below, it creates the ssh connection, and then sends a sudo su -, then my password, and then sends a line that would require sudo access to do (I have also added p.interact() a few times to make sure it is at root). The problem I am having, is with returning the output of the commands I run. In the end I am wanting to run some top commands, and some du -h, and other(much more complex) space commands. But currently when it tries to print p.before, I get:
Traceback (most recent call last):
File "./ssh.py", line 37, in <module>
print p.before()
TypeError: 'str' object is not callable
Here is the script I am working from(edited to remove my pass and such)
#!/usr/bin/env python
import pexpect
import struct, fcntl, os, sys, signal
def sigwinch_passthrough (sig, data):
# Check for buggy platforms (see pexpect.setwinsize()).
if 'TIOCGWINSZ' in dir(termios):
TIOCGWINSZ = termios.TIOCGWINSZ
else:
TIOCGWINSZ = 1074295912 # assume
s = struct.pack ("HHHH", 0, 0, 0, 0)
a = struct.unpack ('HHHH', fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ , s))
global global_pexpect_instance
global_pexpect_instance.setwinsize(a[0],a[1])
ssh_newkey = 'Are you sure you want to continue connecting'
p=pexpect.spawn('ssh user#localhost')
i=p.expect([ssh_newkey,'password:',pexpect.EOF,pexpect.TIMEOUT],1)
if i==0:
print "I say yes"
p.sendline('yes')
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==1:
print "I give password",
p.sendline("mypassword")
elif i==2:
print "I either got key or connection timeout"
pass
elif i==3: #timeout
pass
global global_pexpect_instance
global_pexpect_instance = p
p.sendline("sudo su -")
p.sendline("mypasswd")
p.sendline("mkdir /home/user/test")
print p.before
I am working off of this link: http://linux.byexamples.com/archives/346/python-how-to-access-ssh-with-pexpect/
Any help is much appreciated.
EDIT: As Armin Rigo pointed out below. I was calling to p.before as a function like p.before(). Stupid mistake on my part, as this explains why I was getting this error today, and not yesterday when I was trying this. After making that change to my script, and modifying the command being sent, print p.before, and no output is returned. Any other ways to return output from a sendline() command?
Use logfile, that logfile is store all output in terminal.use that example code:-
child = pexpect.spawn("ssh user#localhost")
child.logfile = open("/tmp/mylog", "w")
child.expect(".*assword:")
child.send("guest\r")
child.expect(".*\$ ")
child.sendline("python -V\r")
open the log file and see everything in terminals event
To fetch the complete output after sendline use child.read()
e.g.
cmd_resp = pexpect.spawnu(cmd) # for execution of the command
str_to_search = 'Please Enter The Password'
cmd_resp.sendline('yes') # for sending the input 'yes'
resp = cmd_resp.expect([str_to_search, 'password:', EOF], timeout=30) # fetch the output status
if resp == 1:
cmd_resp.sendline(password)
resp = cmd_resp.expect([str_to_search, 'outputString:', EOF], timeout=30)
print(cmd_resp.read()) # to fetch the complete output log
p.before is a string - not a function. To see the output you have to write
print p.before.
Hope this might help you

Categories

Resources