I have a python script to copy all files from a USB storage device to a target folder in my Ubuntu machine. I have never programmed in Python before.
import os
import shutil
from shutil import copytree, ignore_patterns
files = os.listdir('/media/user/HP drive')
destination = '/home/user/Documents/Test/%s'
try :
for f in files:
source = '/media/user/HP drive/%s' % f
copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
except Exception as e:
print(e)
The above script runs fine but it creates a folder %s
inside the Test folder with the lock symbol. When I remove the %s and just use
destination = '/home/user/Documents/Test/'
It gives me [Errorno 17] file exists
.
This is the bash script(copy.sh) which I want to run when a USB device is mounted.
#!/bin/sh
python /var/www/html/copy_flash.py #This doesn't work.
# echo "My message" > /var/www/html/thisisaverylongfilename.txt #This works
So the python command is not working but the echo command does when I plug in a USB.
Here's the line I added in /etc/udev/rules.d/test.rules
ACTION=="add",KERNEL=="sdb*", RUN+="/var/www/html/copy.sh"
Is it because the USB drive is not ready when the bash script runs?
In order to not use %s you can use the format method.
source = '/media/users/HP/{path}'.format(path=your_filename_here)
You can use any name within the braces which will create the keyword arguments of format. You can also use numbers which are converted to positional arguments. An example:
'Hello {0}! Good {1}'.format('DragonBorn', 'Evening!')
copytree from shutil also requires that the destination not exist. So you will need to check if the destination exists and remove it if it does. You can use os.rmdir and os.path.exists for that. shutil may also have an equivilent function.
https://docs.python.org/3.5/library/shutil.html#shutil.copytree
You can do this check and copy the tree with:
if os.path.exists(destination):
if os.listdir(): # If the directory is not empty, do not remove.
continue
os.rmdir(destination)
shutil.copytree(source, destination)
If you want to remove the entire tree under the directory you can use shutil.rmtree().
if os.path.exists(destination):
shutil.rmtree(destination)
Solution for 1: How do I copy the USB drive contents in a regular folder and not in %s?
I made it to work from Ethan's answer.
Solution for 2: How do I actually copy the contents?
Okay so I found out about systemd from this answer and the advantage it has over udev rule is that the script really fires after mount, not after adding system device which is why my python script was unable to copy the files because the script was running before the device was actually mounted.
I removed the file /etc/udev/rules.d/test.rules
and created a new file in /etc/systemd/system/copy.service with the contents:
[Unit]
Description=My flashdrive script trigger
Requires=media-YourMediaLabel.mount
After=media-YourMediaLabel.mount
[Service]
ExecStart=/home/you/bin/triggerScript.sh
[Install]
WantedBy=media-YourMediaLabel.mount
Run this command sudo systemctl list-units -t mount
. Find your device and replace media-YourMediaLabel.mount
above with your device unit.
Then you have to start/enable the service:
sudo systemctl start copy.service
sudo systemctl enable copy.service
And that's it. Your USB device's content will be automatically copied in your target destination after it's mounted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With