I have this function to get a file type :
def get_file_type():
try:
cmd = ['/usr/bin/file', '/home/user']
p = Popen(cmd, stdout=PIPE).communicate()[0]
p = str(p).split(':')[1:]
if len(p) > 1:
' : '.join(p).strip().replace('\\n', '')
else:
p = p[0].strip().replace('\\n', '')
print(p)
except CalledProcessError:
print('unknown')
But it returns this : directory'
The ending apostrophe is not a typo, it is what bothers me. And I don't understand why (not that it bothers me.. ;) )
Thank you
The problem is that you're treating bytes as a string and you're using Python3. So what you're getting when you call str(p) looks like this:
"b'/home/user: directory\\n'"
You could fix this by doing p.decode().split instead of str(p).split
Related
I am getting this error in my code and I have never had it before and I have no idea what is causing it to happen. Does anyone know how I can fix my code and can someone explain what this error means?
ERROR: Traceback:
in <module
in simple_encoder
EOFError: EOF when reading a line
def simple_encoder(s):
users_string = input("please enter a scentence to encode")
users_stringlower = users_string.lower()
encodedstr = users_string
for x in range(0, len(users_string)):
indexnumber = 0
count = users_stringlower.count[indexnumber]
LetterToEncode = users_string[indexnumber]
if count > 1:
encodedstr = encodedstr.replace(LetterToEncode, ']')
elif count == 1:
encodedstr = encodedstr.replace(LetterToEncode, '[')
indexnumber = indexnumber + 1
Usually, EOFError refers to an End Of File error. That means that your program called input() but failed to have any available input to read.
We cannot run the code you posted because we're missing some variables, like NumOfIterations.
I'll trying to wite a program that search a pattern to find when a check_output of an ifconfig was given. So I define a function, in a condition where the "interface" has got a MAC, I can go ahead, while if there's no MAC address and the object type is None, I can't go ahead with the else condition. Please, what I'm wrong?
def get_current_mac(interface):
pattern = r"([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}"
ifconfig_result = (check_output(["ifconfig", interface])).decode('utf-8')
mac_address_result = (re.search(pattern, ifconfig_result).group())
if mac_address_result:
print("Current MAC = " + mac_address_result)
else:
print ('No MAC')
Thanks in advance.
Best regards,
RG
You can't call .group() on None. You have to call that in the if.
def get_current_mac(interface):
pattern = r"([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}"
ifconfig_result = check_output(["ifconfig", interface]).decode('utf-8')
mac_address_result = re.search(pattern, ifconfig_result)
if mac_address_result:
print("Current MAC = " + mac_address_result.group())
else:
print ('No MAC')
Whetever I do, I get this error when trying to print anything from 'ip_macAddr' using an index.
Type is 'list' so I don't get why. The only explanation I have is that there's some type of caracter coming from the stdout of that subprocess that's messing things up.
Also I tried converting to string with no different result.
At this point I have ne clue.
Thanks for your help!
Code
#!/usr/bin/env python3.7
import sys
import subprocess
import os
IP_NETWORK = '192.168.254.10'
IP_DEVICE = '192.168.254.194'
proc = subprocess.Popen(['ping', IP_NETWORK], stdout=subprocess.PIPE)
while True:
line = proc.stdout.readline()
# print(line)
if not line:
break
connected_ip = line.decode('utf-8').split()[3].replace(':','')
proc2 = subprocess.Popen(['ip', 'neigh', 'show', 'to', connected_ip], stdout=subprocess.PIPE)
ip_macAddr = proc2.stdout.readline().decode('utf-8').split()
print(connected_ip)
# print(type(ip_macAddr))
print(ip_macAddr[0])
Error
IndexError: list index out of range
edit 1
The output of print(ip_macAddr) would be: ['192.168.254.10', 'dev', 'wlp61s0', 'lladdr', '88:88:a1:b2:c3:88', 'REACHABLE']
edit 2
print(type(ip_macAddr)) returns <class 'list'>
edit 3
Traceback
Traceback (most recent call last):
File "./device-connected-to-network.py", line 34, in <module>
print(ip_macAddr[0])
IndexError: list index out of range
This would happen using ANY index and I also tried using:
print(ip_macAddr[0]) or ip_macAddr = proc2.stdout.split()[0]
Again; same result using ANY index # and print(type(ip_macAddr)) returns type 'list'.
Another exemple;
The output of print(ip_macAddr)is ['192.168.254.10', 'dev', 'wlp61s0', 'lladdr', '74:83:c2:d2:a4:12', 'REACHABLE'].
So, if I do (in another file) - using index #4:
a = ['192.168.254.10', 'dev', 'wlp61s0', 'lladdr', '11:22:a1:b2:c3:33', 'REACHABLE']
print(type(a))
print(a[4])
The output is:
<class 'list'>
11:22:a1:b2:c3:33
So works as expected in this context, but not within the actual program.
split()[3] will fail with an IndexError on any line which has less than four whitespace-separated fields.
A common fix is to simply skip lines with fewer fields.
Similarly, if ip produces an empty string, splitting it produces an empty list, which you can't get the first element of.
You can also simplify your code by passing in text=True, and use subprocess.run() where you don't particularly need Popen(). I have also removed unused imports.
#!/usr/bin/env python3.7
import subprocess
IP_NETWORK = '192.168.254.10'
IP_DEVICE = '192.168.254.194'
proc = subprocess.Popen(['ping', IP_NETWORK],
stdout=subprocess.PIPE, text=True)
while True:
line = proc.stdout.readline()
# print(line)
if not line:
break
fields = line.split()
if len(fields) < 4:
continue
connected_ip = fields[3].replace(':','')
proc2 = subprocess.run(
['ip', 'neigh', 'show', 'to', connected_ip],
capture_output=True, text=True)
result = proc2.stdout
if not result:
continue
ip_macAddr = result[0]
print(connected_ip)
# print(type(ip_macAddr))
print(ip_macAddr)
Even better, trap and report any exceptions.
try:
proc2 = subprocess.run(
['ip', 'neigh', 'show', 'to', connected_ip],
capture_output=True, text=True,
check=True) # important
result = proc2.stdout
except CalledProcessError as exc:
print('`ip\' for', connected_ip, 'failed:', exc)
continue
I'm currently creating a programming language in Python 3.6 and for some reason, the following code produces an IndexError: string index out of range.
When I try to execute the following code in a Windows Batch File:
#echo off
python run-file.py test.ros
pause
But I'm getting the following output:
Traceback (most recent call last):
File "run-file.py", line 16, in <module>
if not(value[1][0] == "!") and ignoreline == False:
IndexError: string index out of range
Press any key to continue . . .
The run-file.py file looks like this:
from sys import argv as args
from sys import exit as quit
import syntax
try:
args[1]
except IndexError:
print("ERROR: No ROS Code file provided in execution arguments")
print("Ensure the execution code looks something like this: python run-file.py test.ros")
with open(args[1]) as f:
ignoreline = False
content = f.readlines()
content = [x.strip() for x in content]
for value in enumerate(content):
if not(value[1][0] == "!") and ignoreline == False:
firstpart = value[1].split(".")[0]
lenoffirstpart = len(value[1].split(".")[0])
afterpart = str(value[1][lenoffirstpart + 1:])
apwithcomma = afterpart.replace(".", "', '")
preprint = str(firstpart + "(" + apwithcomma + ")")
printtext = preprint.replace("(", "('")
lastprinttext = printtext.replace(")", "')")
try:
exec(str("syntax." + lastprinttext))
except Exception as e:
template = "ERROR: An error of type {0} occured while running line {1} because {2}"
message = template.format(
type(e).__name__, str(value[0] + 1), str(e.args[0]))
print(message)
quit(1)
elif content[value[0]][0] == "!!!":
ignoreline = not(ignoreline)
quit(0)
The syntax.py file looks like this:
def print_message(contents=''):
print(contents)
The test.ros file looks like this:
! This is a single line comment
!!!
This line should be ignored
and this one as well
!!!
print_message.Hello World
The problem appears to be in line 16 of the run-file.py file:
if not(value[1][0] == "!") and ignoreline == False:
I've already tried replacing value[1][0] with (value[1])[0] and other combinations with brackets to no avail.
It seems like when I try to print the value it behaves as expected and gives me ! which is the first character of the test.ros file but for some reason, it throws an exception when it's in the if statement.
If you want any more of the source, it's on Github and you can find the exact commit containing all the files here
Update/Solution
Big thanks to Idanmel and Klaus D. for helping me resolve my issue. You can view the changes I've made here
This happens because the 2nd line in test.ros is empty.
You create content in this example to be:
['! This is a single line comment',
'',
'!!!',
'This line should be ignored',
'and this one as well',
'!!!',
'',
'print_message.Hello World']
When you try to access content[1][0], you get an IndexError because it's an empty string.
Try removing the empty lines from content by adding an if to the list comprehenssion:
content = [x.strip() for x in content if x.strip()]
I am using Python 3.5 on the following code.
def raxml(DIR,cleaned,num_cores,seqtype):
assert cleaned.endswith(".aln-cln"),\
"raxml infile "+cleaned+" not ends with .aln-cln"
assert seqtype == "aa" or seqtype == "dna","Input data type: dna or aa"
assert len(read_fasta_file(DIR+cleaned)) >= 4,\
"less than 4 sequences in "+DIR+cleaned
clusterID = cleaned.split(".")[0]
tree = DIR+clusterID+".raxml.tre"
raw_tree = "RAxML_bestTree."+cleaned
model = "PROTCATWAG" if seqtype == "aa" else "GTRCAT"
if not os.path.exists(tree) and not os.path.exists(raw_tree):
# raxml crashes if input file starts with .
infasta = cleaned if DIR == "./" else DIR+cleaned
cmd = ["raxml","-T",str(num_cores),"-p","12345","-s",\
infasta,"-n",cleaned,"-m",model]
print (" ".join(cmd))
p = subprocess.Popen(cmd,stdout=subprocess.PIPE)
out = p.communicate()
assert p.returncode == 0,"Error raxml"+out[0]
try:
os.rename(raw_tree,tree)
os.remove("RAxML_info."+cleaned)
os.remove("RAxML_log."+cleaned)
os.remove("RAxML_parsimonyTree."+cleaned)
os.remove("RAxML_result."+cleaned)
os.remove(DIR+cleaned+".reduced")
except: pass # no need to worry about extra intermediate files
return tree
It runs and returns the following code:
"raxml_wrapper.py", line 30, in raxml
assert p.returncode == 0,"Error raxml"+out[0]
TypeError: Can't convert 'bytes' object to str implicitly
Initially, I tried the following:
p = subprocess.Popen(cmd,stdout=subprocess.PIPE)
p = p.decode('utf-8')
out = p.communicate()
assert p.returncode == 0,"Error raxml"+out[0]
That didn't fix the issue at all. I have looked at similar questions, but I cannot come up with a solution to this. I would appreciate some help on this.
Thanks!
p, a Popen object, doesn't have a .decode(...) member.
You need to actually decode the output
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
out, _ = p.communicate()
out = out.decode('utf-8')
assert p.returncode == 0, 'Error raxml' + out[0]
That said, this code can be improved to use subprocess.check_output:
# does roughly the same thing, you'll get `subprocess.CalledProcessError` instead of `AssertionError`
out = subprocess.check_output(cmd).decode('UTF-8')
Or if you happen to be using python3.6+
out = subprocess.check_output(cmd, encoding='UTF-8')
I do not know exactly what your p.communicate() method does, but it seems that it returns a byte object as a result. And this piece of code, cannot add this byte object to "Error raxml" str object:
assert p.returncode == 0,"Error raxml"+out[0]
Maybe you should try converting it to str as this:
assert p.returncode == 0,"Error raxml"+str(out[0])