I thought doing a sync in my bash script would force the file to be completely written out. When I looked at the thumb drive, it showed all the files I had copied, but after a power supply failure, the usb drive showed 0 files. Do I have to eject the drive manually or is there something I can do programmatically in my script?
If you want to eject the usb device from your bash script a simple umount on the device should do the trick. For example
mount /dev/usb /mnt/usb
# Your copy operations here... then on success:
umount /mnt/usb
you can also try to use the linux sync instruction that syncronize writing over disk if you're usb key is using a journalized file system
Related
I know I can mount a block device like SD card by the following command;
mount /dev/mmcblk /mnt/SD
Then I can use ls and cp command in the filesystem in SD. I can also execute a file in it.
However, I don't know how to mount a character device like eeprom or nor flash which is controled by I2C or SPI.
I want to make a embedded system that doesn't depend on SD. My goal is to use ls or cp command, and execute some files in such devices like you can do it in SD.
Actually, I made an original I2C driver in which I can open, read and write data through /dev/myi2cdriver.
But when I mount that device file, error message appears saying "device is not a block device" and mount fails.
Could you give me advices?
As you have seen, this isn't intended to work.
You could probably copy /dev/myi2cdriver to a file and mount -o loop that. You might be able to just mount -o loop your character device directly.
Alternatively, develop a block device driver?
I am trying to figure out if there is a way to automatically run a bash script that I created and stored on a USB device, so when I plug in the USB device it automatically runs the bash script (e,g. getusbinfo.sh) and outputs the USB info to a text file (can write this text file to USB or Linux machine). I looked at a lot of solutions, and a lot of the posts seem to launch the bash script that is stored on the Linux machine rather than the USB itself which is different than what I am looking for.
Any insight would help!
It is possible to run script from connected usb pendrive. Here is the solution:
/etc/udev/rules.d/10-usb.rules:
ACTION=="add" ENV{DEVNAME}=="/dev/sd*" ENV{DEVTYPE}=="disk", RUN+="/root/sk $env{DEVNAME}"
/root/sk:
#!/bin/sh
d=$1
mount ${d}1 /mnt/usb/
/mnt/usb/getusbinfo.sh
umount ${d}1
but it assumes that it must be partition 1 mounted from this pendrive.
Is there a Bash script and/or daemon that I can write that will detect a specific USB drive and then sync that drive with a directory?
For future reference, here's how to run a bash script upon detection of a USB drive.
Connect your device and run lsusb to retrieve the device's info. You should see something similar to this:
$ lsusb
Bus 002 Device 039: ID 0bc2:2100 Seagate RSS LLC
In this case, the vendor ID of the device is 0bc2 and the product ID is 2100.
Now you can create your UDEV rule using a text editor of your choice.
$sudo vi /etc/udev/rules.d/85-my_usb_device_rule.rules
And add this:
ACTION=="add", SUBSYSTEM=="usb", SYSFS{idVendor}=="0bc2",
SYSFS{idProduct}=="2100", RUN+="/home/myhome/my_script"
/home/myhome/my_script is the path to your script which it would do whatever you want.
To make sure the detection script will execute right away, run this command to reload the UDEV rules:
$sudo udevadm control --reload-rules
This was tested on Fedora 14.
I didn't do it myself, but you can try udev rules like this:
# Hitachi SimpleDrive mini, model HTS545050B9A300 (500 GB USB HDD)
SUBSYSTEM=="block", ATTR{size}=="976768002", ATTRS{product}=="SimpleDrive mini", ATTRS{serial}=="2512009121920487", ACTION=="add", RUN+="/lib/udev/local.usb.hdd.sh add $devpath"
Place it in /etc/udev/rules.d/90-local.rules or similar place, certainly dependable on your OS.
Here is an example python deamon that you could use for the listening part, then copying the files to your directory shouldn't be a problem.
There are excellent answers here already but depending on your use case, it could be as simple as
[ -d /run/media/$USER/USB_STICK ] && do_stuff
USB_STICK here is the label of the usb stick.
I am a Windows admin and dev, I do not generally work with Linux so forgive me if this is in some way obvious.
I have a not so good Linux box, some older version of Open SUSE, and I have a script that unmounts the USB thumb drive, formats it, and then waits for the device to become ready again before it runs a script that does a copy/MD5 checksum verification on the source and destination file to ensure the copy was valid. The problem is that on one box the USB thumb drive does not become ready after the format in a consistent way. It takes anywhere from 1 to 2+ minutes before I can access the drive via /media/LABELNAME.
The direct path is /dev/sdb but, of course, I cannot access it directly via this path to copy the files. Here is my shell script as it stands:
#!/bin/bash
set -e
echo "Starting LABELNAME.\n\nUnmounting /dev/sdb/"
umount /dev/sdb
echo "Formatting /dev/sdb/"
mkfs.vfat -I -F32 -n "LABELNAME" /dev/sdb
echo "Waiting on remount..."
sleep 30
echo "Format complete. Running make master."
perl /home/labelname_master.20120830.pl
Any suggestions? How might I wait for the drive to become ready and detect it? I have seen Detecting and Writing to a USB Key / Thumb DriveAutomatically but quite frankly I don't even know what that answer means.
It seems that you have some automatic mounting service running which detects the flash disk and mounts the partition. However, you already know what the partition is, so I recommend that you simply mount the disk in your script, choosing a suitable mount point yourself.
mkfs.vfat -I -F32 -n "LABELNAME" /dev/sdb
echo "Format complete, remounting"
mount /dev/sdb $mountpoint #<-- you would choose $mountpoint
echo "Running make master."
perl /home/labelname_master.20120830.pl
I am running Ubuntu Precise.
In my /etc/init.d I have a bash script that, does the following on startup:
loop mounts an image on an NTFS drive. That image contains an ext2 file system with a directory named home
It then does a mount with a --rbind option that mounts the home within the image file onto /home.
Works well so far, although having open files in /home doesn't prevent the loop mount from being unmounted.
Unfortunately, Nautilus displays the loop mount in the list of removable drives with an icon that allows a user to unmount the loop mount. Unmounting the drive on which /home is mounted is not conducive to a well running system.
How can I keep Nautilus from displaying this loop mounted device?
man udisk(7) says that one of the 'Influential device properties in the udev database' is:
UDISKS_PRESENTATION_HIDE
If set to 1 this is a hint to presentation level software that the device should not be shown to the user.
I assume that setting this property on the /dev/loop would tell Nautilus not to show the device.
How would I set the UDISKS_PRESENTATION_HIDE in a bash script?
The answer should now be updated (at least for Ubuntu 12.10).
You don't have to write this anymore (as was originally written in the other answer):
KERNEL=="sda1", ENV{UDISKS_PRESENTATION_HIDE}="1"
KERNEL=="sdb2", ENV{UDISKS_PRESENTATION_HIDE}="1"
Instead, you should write this:
KERNEL=="sda1", ENV{UDISKS_IGNORE}="1"
KERNEL=="sdb2", ENV{UDISKS_IGNORE}="1"
The rest is the same :)
You have to write the following on /etc/udev/rules.d/99-hide-disks.rules:
KERNEL=="sdxy", ENV{UDISKS_PRESENTATION_HIDE}="1"
Where sdxy is the partition inside /dev. You can easily find the partition by running mount (but I think you already know it).
Another approach is to mount the device somewhere other than under /media. I chose under /run, which allows /mnt to be used for temporary mounts.
According to the udisk page on archlinux wiki and to sum up the others answers:
Add a file named /etc/udev/rules.d/99-hide-disks.rules
For udisk:
# hide the device sda1
KERNEL=="sda1", ENV{UDISKS_PRESENTATION_HIDE}="1"
For udisk2:
# hide the device sda1
KERNEL=="sda1", ENV{UDISKS_IGNORE}="1"
# hide the device sda2 using UUID
# use: blkid /dev/sda2 to get the UUID of /dev/sda2
ENV{ID_FS_UUID}=="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX", ENV{UDISKS_IGNORE}="1"