简体   繁体   English

运行bash脚本以在USB设备安装后自动从USB设备复制内容

[英]Run bash script to automatically copy contents from USB device after USB device mount

I have a python script to copy all files from a USB storage device to a target folder in my Ubuntu machine. 我有一个python脚本将所有文件从USB存储设备复制到我的Ubuntu机器中的目标文件夹。 I have never programmed in Python before. 我之前从未用Python编程。

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. 上面的脚本运行正常,但它使用锁定符号在Test文件夹中创建了一个文件夹%s When I remove the %s and just use 当我删除%s并只是使用

destination = '/home/user/Documents/Test/'

It gives me [Errorno 17] file exists . 它给了我[Errorno 17] file exists

This is the bash script( copy.sh ) which I want to run when a USB device is mounted. 这是我想在安装USB设备时运行的bash脚本( copy.sh )。

#!/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. 所以python命令不起作用,但是当我插入USB时,echo命令会这样做。

Here's the line I added in /etc/udev/rules.d/test.rules 这是我在/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? 是因为当bash脚本运行时USB驱动器还没有准备好吗?

  1. How do I copy the USB drive contents in a regular folder and not in %s? 如何将USB驱动器内容复制到常规文件夹而不是%s?
  2. How do I actually copy the contents? 我如何实际复制内容?

In order to not use %s you can use the format method. 为了不使用%s,您可以使用格式化方法。

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. 来自shutil的copytree也要求目标不存在。 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. 您可以使用os.rmdir和os.path.exists。 shutil may also have an equivilent function. shutil也可能具有等效功能。

https://docs.python.org/3.5/library/shutil.html#shutil.copytree 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(). 如果要删除目录下的整个树,可以使用shutil.rmtree()。

if os.path.exists(destination):
    shutil.rmtree(destination)

给出python的完整路径:

/usr/bin/python /var/www/html/copy_flash.py

Solution for 1: How do I copy the USB drive contents in a regular folder and not in %s? 1的解决方案:如何将USB驱动器内容复制到普通文件夹而不是%s?

I made it to work from Ethan's answer . 我从Ethan的回答中做到了。

Solution for 2: How do I actually copy the contents? 解决方案2:如何实际复制内容?

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. 好吧所以我从这个答案中发现了systemd ,并且它对udev规则的优势在于脚本真的在mount之后触发,而不是在添加系统设备之后,这就是为什么我的python脚本无法复制文件,因为脚本之前运行该设备实际安装。

I removed the file /etc/udev/rules.d/test.rules 我删除了文件/etc/udev/rules.d/test.rules

and created a new file in /etc/systemd/system/copy.service with the contents: 并在/etc/systemd/system/copy.service中创建了一个新文件,其内容如下:

[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 . 运行此命令sudo systemctl list-units -t mount Find your device and replace media-YourMediaLabel.mount above with your device unit. 找到您的设备并用您的设备单元替换上面的media-YourMediaLabel.mount

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. 安装后,USB设备的内容将自动复制到目标目标中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM