Hello, I’m back.

Yesterday when I was on the toilet, I had the idea that when you plug in the USB, it can automatically execute the program on the USB. Checked, found that only Windows can, specific we can also search (search keywords USB Autorun) to. But if I wanted, for example, to automatically copy important files from a USB drive to a local location or upload them to a server in the background when a USB drive was plugged in, I needed special software assistance.

So I wondered if I could write a program in Python and have it run in the background. Every time a U disk is inserted, it automatically copies important files.

How to determine whether a USB flash drive is inserted?

First of all, we opened the PC terminal and went to the /Volumes directory. When we inserted the USB disk, we found that it was mounted under the directory. That is to say, we only had to scan the directory at a fixed time. Sleep (3) to keep the program running and check the /Volumes/ directory every three seconds. If there are extra folders, copy them to another folder.

# encoding=utf-8from time import sleepimport os, Shutilusb_path = "/Volumes/"content = os.listdir(usb_path) # os.listdir(path) New_content = os.listdir(usb_path) = content: # exit break if an exception is found, i.e. an extra folder; Sleep (3)x = [item for item in new_content if item not in content]# sleep(3)x = [item for item in new_content if item not in content] Pythonicshutil.copytree (os.path.join(usb_path, x[0]), '/Users/home/usb_copy')# shutil.copytree copies all contents of the directory into /Users/home/usb_copy, # into its own home directoryCopy the code

As the title suggests, we actually did the virus in 10 lines (11, full :). We can see that the usb directories are all in the home directory after half a minute of insertion.

How do I selectively copy files?

We’ve just written a very simple script to test the idea, but there are still problems. The reason why I was able to copy all the files in the USB flash drive quickly is that there are only two or three files in the USB flash drive, and the size is no more than 15MB. If the target usb drive has a lot of movies and music files that we don’t need, our program should be able to skip them, select only important files like.docx and.ppt, copy only the files that have been modified recently, or exclude all files larger than 5M. Can we do that in Python? Of course!

Os. walk Recurses all files in the folder

Here I put up a tutorial from someone else. You can get a sense of it, but I get a sense of it.

Let me give you an example.

TXT and folder123. Folder1 contains file4. TXT and folder4

testwalk touch file1.txt file2.txt file3.txt testwalk mkdir folder1 folder2 folder3 testwalk cd folder1 folder1 touch file4.txt && mkdir folder4 folder1 cd .. # create these files and folders, you can also create # tree on a graphical interface which is a fun command, Can visually display file path testwalk tree. / testwalk ├ ─ ─ file1. TXT ├ ─ ─ file2. TXT ├ ─ ─ file3. TXT ├ ─ ─ folder1 │ ├ ─ ─ file4. TXT │ └ ─ ─ ├── Let directories directories, 4 filesCopy the code

Now let’s test that out

import os for root, dirs, files in os.walk("./testwalk/"): for name in files: print(os.path.join(root, name)) for name in dirs: Print (OS) path) join (root, name) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the results:  ./testwalk/folder1/file4.txt ./testwalk/folder1/folder4 ./testwalk/file2.txt ./testwalk/file3.txt ./testwalk/file1.txt ./testwalk/folder2 ./testwalk/folder3 ./testwalk/folder1Copy the code

Root stores the current location and searches all folders under./testwalk/ as the root directory

for root, dirs, files in os.walk("./testwalk/", topdown=False):
    print(root)
./testwalk/folder2
./testwalk/folder3
./testwalk/folder1/folder4
./testwalk/folder1
./testwalk/
Copy the code

View dirS separately

for root, dirs, files in os.walk("./testwalk/"):
    for name in dirs:
        print(os.path.join(root, name))

./testwalk/folder2
./testwalk/folder3
./testwalk/folder1
./testwalk/folder1/folder4
Copy the code

View files separately

for root, dirs, files in os.walk("./testwalk/", topdown=False):
    for name in files:
        print(os.path.join(root, name))

./testwalk/file2.txt
./testwalk/file3.txt
./testwalk/file1.txt
./testwalk/folder1/file4.txt
Copy the code

Ok, now we need to recurse to the USB folder, find all the files, check the size, if less than, say 3M, copy it into home, larger than, delete it.

Shutil module

import shutil
>>> help(shutil)
>>> dir(shutil)
['Error', 'ExecError', 'SpecialFileError', 'WindowsError', 
'_ARCHIVE_FORMATS', '_BZ2_SUPPORTED', '_ZLIB_SUPPORTED', '__all__',
 '__builtins__', '__doc__', '__file__', '__name__', '__package__',
 '_basename', '_call_external_zip', '_destinsrc', '_get_gid', '_get_uid',
 '_make_tarball', '_make_zipfile', '_samefile', 'abspath', 
'collections', 'copy', 'copy2', 'copyfile', 'copyfileobj',
 'copymode', 'copystat', 'copytree', 'errno', 'fnmatch', 
'get_archive_formats', 'getgrnam', 'getpwnam', 'ignore_patterns', 
'make_archive', 'move', 'os', 'register_archive_format', 'rmtree', 
'stat', 'sys', 'unregister_archive_format']
Copy the code

Okay, I don’t know. I have to read the official document. Docs.python.org/2/library/s…

For example, if you want to copy file1. TXT to folder2:

>>> shutil.copy2('./file1.txt', '. / folder2) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- I'm line -- -- -- -- -- -- -- -- -- -- - ls folder2 file1. TXTCopy the code

There are also a number of tools in Shutil that are not detailed here.

Os.path.getsize () Checks the size

Os.path. getSize (file name) returns a number in bytes. If it is used to view the file size, we need to manually write a function that converts it to an easy-to-read form.

movie = /Users/home/somemovie.rmvb def convert_bytes(num): # this function will convert bytes to MB.... GB... Etc for x in [' bytes', 'KB', 'MB', 'GB', 'TB] : if num < 1024.0: Return "%3.1f %s" % (num, x) num /= 1024.0 def getDocSize(path): try: size = os.path.getsize(path) return size except Exception as err: Print (err) Print (convert_bytes(getDocSize(movie))Copy the code

The file size is smaller than 3M (3M = 3 1024 KB = 3 1024 x 1024 Byte)

for root, dirs, files in os.walk(os.path.join(usb_path, x[0])): #MyUSB location
    for name in files:
        file = os.path.join(root, name)
        if os.path.getsize(file) < 3*1024*1024:
            shutil.copy2(file, target_folder)
Copy the code

Shutil.copy2 is used to copy files of the selected size into our target folder

How do I specify file types

This is where regular expressions come in to help.

Regular expressions are a lot of stuff, and python Core Programming devoted an entire chapter to it, so we won’t go into it. Here is the official document for those interested. Docs.python.org/2/library/r…

Here, we make the specified file suffix and the specified file size available to copy into our target file: don’t forget to import re

import re
...
regex_filename = re.compile('(.*zip$)|(.*rar$)|(.*docx$)|(.*ppt$)|(.*xls$)')
for root, dirs, files in os.walk(os.path.join(usb_path, x[0])): #MyUSB location
    for name in files:
        file = os.path.join(root, name)
        if regex_filename.match(file) and os.path.getsize(file) < 1024*1024:
            shutil.copy2(file, target_folder)
Copy the code

File types can be better specified with more complex regular expressions

Filter files based on modification time

>>> from os.path import *
>>> help(getmtime)
getmtime(filename)
    Return the last modification time of a file, reported by os.stat().

>>> help(getctime)
getctime(filename)
    Return the metadata change time of a file, reported by os.stat().
Copy the code

At this point I create a file in the directory called newFile

>>> getcTime ("newfile") 1522746383.716875 Import time >>> time.ctime(1522746383.716875) 'Tue Apr 3 17:06:23 2018' help(time.ctime)ctime(...) Ctime (seconds) -> string Convert a time in seconds since the Epoch to a string in local time. This is equivalent to asctime(localtime(seconds)). When the time tuple is not present, current time as returned by localtime() is used.Copy the code

In summary, filtering the modification time of each file can only copy files that have been modified or added recently or in a specific period, which is useful in certain situations.

conclusion

In fact, the title so just to attract attention, this is a small program, not a virus. I would like to use this example to demonstrate python’s powerful ability to handle files and to inspire people to learn more. The above implementation is based on MacOS, Linux should be the same, Windows with minor modifications can be successful.

This article is from the Python Enthusiast Community, a partner of the Cloud Computing community. For more information, you can follow the Python Enthusiast Community.