How to wait for the copying process (cp) to finish?
Solution 1
I don't know why changing the kernel name would have made a difference (perhaps sd*1
runs after sd*
allowing a bit more time for work to get done?), but udev doesn't like long-running actions in events:
Starting daemons or other long running processes is not appropriate for udev; the forked processes, detached or not, will be unconditionally killed after the event handling has finished.
Original nohup
suggestion
I originally suggested nohup
before fully reading my own links :) -- which suggest that this may not actually work
udev rule:
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z]1" SYMLINK+="usbflash", RUN+="/path/to/mywrapper.sh"
mywrapper.sh
(Note: if you don't redirect the output nohup may litter your directory with a nohup.out
file):
#!/bin/sh
nohup /path/to/myscript.sh >/log/myscript.log 2>&1 &
Then myscript.sh
can be what it is.
Newer systemd
suggestion
The third link below suggests firing off a systemd service when the device is plugged in. That blog entry does more work than I think you need due to ensuring that the device information is passed to the service, I think you can get away with simply using systemd as your method of daemonization:
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z]1" SYMLINK+="usbflash", RUN+="/usr/bin/systemctl start my-usb-backup.service"
With a simple oneshot service my-usb-backup.service
:
[Unit]
Description=run myscript
[Service]
Type=oneshot
ExecStart=/path/to/myscript.sh
See also:
- How to run long time process on Udev event?
- What is the easiest way to “detach/daemonize” a Bash script?
- Proper(-ish) way to start long-running systemd service on udev event (device hotplug)
- More than you wanted to know about systemd
Solution 2
There is no point in a wait
for a command unless it's run in the background (which yours aren't). What you may be missing is a sync
to force all writes to the media, although that should happen as part of the umount
command.
I'd be interested to see if this simplified script works as you want:
#!/bin/bash
#
export PATH=/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin
mkdir -p /mnt/usb
if mount /dev/usbflash /mnt/usb
then
service omxd stop
rm -r /path/to/myfolder/*
cp -f /mnt/usb/*.mp4 /path/to/myfolder/
cp -f /mnt/usb/*.avi /path/to/myfolder/
sync
umount /mnt/usb
sync
shutdown -h now
fi
I must admit I'm a little puzzled, as your description seems to suggest you want to update files on the USB stick. But your code updates files in /path/to/my/folder
from the USB stick rather than writing to /mnt/usb/...
Related videos on Youtube
Comments
-
Omid1989 almost 2 years
I want my RPi 2 (with
MiniBian
(a minimal version of Debian-basedRaspbian
OS) as its OS) to execute a script when it detects a USB flash memory is inserted. So this is what I have done:I created
/etc/udev/rules.d/10-usbstick.rules
with these contents:ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd*" SYMLINK+="usbflash", RUN+="/path/to/myscript.sh"
And then created
/path/to/myscript.sh
with these contents:#!/bin/bash mount /dev/usbflash /mnt/ service omxd stop rm -r /path/to/myfolder/* cp -f /mnt/*.mp4 /path/to/myfolder/ cp -f /mnt/*.avi /path/to/myfolder/ sleep 1 umount /dev/usbflash halt
Now, when I insert a USB flash memory, it recognizes it, mounts it, stops the
omxd
daemon and removes all the older files.But the problems is that it shuts down (
halt
) before all the files have been copied. I check later and see that only 1 file has been copied, and it has not been copied correctly, like thehalt
command has been executed at the middle of the copying procedure.So, I decided to use
wait
command to ensure that thehalt
command be executed only at the end. I edited the/path/to/myscript.sh
file as this:#!/bin/bash mount /dev/usbflash /mnt/ PID1 = $! wait PID1 service omxd stop rm -r /path/to/myfolder/* PID2 = $! wait PID2 cp -f /mnt/*.mp4 /path/to/myfolder/ PID3 = $! wait PID3 cp -f /mnt/*.avi /path/to/myfolder/ PID4 = $! wait PID4 sleep 1 umount /dev/usbflash PID5 = $! wait PID5 halt
But again the same scenario happens: the system halts at the middle of the copying procedure.
So what's wrong with my system?
What shall I do to tell the system to
halt
only after all the new files have been successfully copied !?
Update 1
Adding
sync
beforeumount
andhalt
didn't work. The same scenario happens again.Update 2
I edited the
/path/to/myscript.sh
file as the following:mkdir -p /mnt/usb if mount /dev/usbflash /mnt/usb then service omxd stop rm -r /path/to/myfolder/* cp -f /mnt/usb/*.mp4 /path/to/myfolder/ cp -f /mnt/usb/*.avi /path/to/myfolder/ sync umount /mnt/usb sync shutdown -h now fi
But it didn't help either! The same scenario happens again! And this time it was worse: it didn't copy any file at all!
Update 3
I changed the
/etc/udev/rules.d/10-usbstick.rules
to the following:ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z]1" SYMLINK+="usbflash", RUN+="/path/to/myscript.sh"
Now it works great. It copies all the files. But there's a new problem: It doesn't shut down!
Update 4
I found something new:
When I run
myscript.sh
directly from the terminal, it works perfect: removes the older files, copies the new files, and shuts down the system. Perfect.So, why doesn't it execute
myscript.sh
perfectly when I call it from udev rules?And is there any other way to shut down the system after it has copied the files !?
-
terdon over 8 yearsComments are not for extended discussion; this conversation has been moved to chat.