Fork me on GitHub

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

developer:mounting_attached_backup_devices [2019/10/23 00:42]
developer:mounting_attached_backup_devices [2018/10/18 23:59] (current)
admin [USB Device Support Tools]
Line 1: Line 1:
 +====== Mounting Attached Devices ======
  
 +This page is dedicated to the development of systems to mount attached devices. The hope is that this page will result in a variety of tools which will be able to assist pre and post action scripts.
 +
 +===== Related Links =====
 +  * [[:Pre and Post Actions]] (information related to the pre and post action script system of LBackup)
 +  * [[developer:​Pre and Post Action Tools]] (Developer Link)
 +  * [[http://​www.macosxhints.com/​article.php?​story=20060930150059172|Prevent partitions from automatically mounting]] (Mac OS X)
 +\\ \\
 +
 +/**
 +  * [[http://​connect.homeunix.com/​unicode/?​p=139|Prevent partitions from automatically mounting]] (Mac OS X)
 +*/
 +
 +===== Support for Mac OS X Devices =====
 +\\ \\
 +
 +==== USB Device Support Tools ====
 +
 +The script below supports mounting attached USB devices by name volume name. There is support for FireWire devices and non-removable drives commented out. This code should work. The script requires improvements in various areas. Improvements are welcomed [[http://​www.lucidsystems.org/​contact|via email]].
 +\\ \\ 
 +The script below is a work in progress. Even though it works it is certainly not an ideal solution.
 +\\ \\ 
 +<​file>​
 +
 +#​!/​usr/​bin/​env ruby
 +#
 +# (C)2009 Henri Shustak
 +# Released Under the GNU GPL
 +# Lucid Information Systems
 +# http://​www.lucidsystems.org
 +#
 +# WARNING : This code is quite speggitfied. Assistance with tiding up it would be great.
 +#
 +# This is a script to detect attached but unmounted volumes by Volume name and mount them.
 +# Tested on the following versions of Mac OS X : 
 +#                         - 10.12.6 intel
 +#                         
 +#
 +#
 +# Knowen Issues :  - If you rename the disk then somtimes the partition will not be detected.
 +#                    If this happens re-partition the disk and try again.
 +#
 +# Version 0.3.2
 +#
 +#
 +# Version History
 +#  0.3.2 - Added support for USB-Hubs and macOS 10.12.6 - made it a bit messy
 +#
 +# Note : Using a (list of) UUID('​s) is generally a good approach to mounting devices. ​
 +#        That is not how this script works. This script mounts volumes via the volume name.
 +#        This approach allows you to add additional devices into a rotation set without
 +#        altering this script or the way you call this script. However, it is extremely ​
 +#        important to be aware of the potential problems which may arise by using the
 +#        volume name to mount a device before you use this script in any kind
 +#        of production setting.
 +#
 +
 +
 +# Check we are running on Mac OS X
 +os_kind = `uname`
 +if os_kind.chomp != "​Darwin" ​
 +    puts "This script is designed to run on darwin."​
 +    exit -1
 +end
 +
 +# Load system profile data 
 +#
 +#   Note : it would be better to use xml - 
 +#          anyone care to make this work 
 +#          with the built in RUBy XML system.
 +#          It requires parsing a Mac OS X .plist  ​
 +#          Assistance with this is greatly appreciated.
 +#
 +
 +
 +# List of detachable drives
 +disks = []
 +
 +# Build a list of detachable USB drives.
 +system_profiler_output = `system_profiler SPUSBDataType | grep -A 1 "​Removable Media: Yes" | grep "BSD Name" | sed 's/^ *//g'`
 +
 +# Add detachable FireWire drives to the list
 +#​system_profiler_output = system_profiler_output + `system_profiler SPFireWireDataType`
 +
 +# Add ATA drives to the list.
 +#​system_profiler_output = system_profiler_output + `system_profiler SPParallelATADataType`
 +
 +# Add SATA dirves to the list
 +#​system_profiler_output = system_profiler_output + `system_profiler SPSerialATADataType`
 +
 +device = system_profiler_output.split("​BSD Name: ")
 +device.each { |d|
 +    if d.to_s.include?​ "​disk"​
 +        disks << "/​dev/"​ + d
 +    end
 +}
 +
 +
 +
 +# Generate a hash of all devices to Volumes names. Disks without volume names will be set to nil
 +#
 +#    Note : Any suggestions on how to improve this are greatly welcomed.
 +
 +$disk_hash = {}
 +disks.each { |d|
 +    diskcom = "​diskutil list #​{d}" ​
 +    partitions_list = `#​{diskcom}`
 +    partitions_list = `echo "#​{partitions_list}"​ | grep -e "​disk*[0-9]s*[0-9]"​ | awk '​{print $NF}'`
 +    partitions = partitions_list.split("​\n"​)
 +    partitions.each { |p|
 +        major_system_version=`uname -v | awk -F "​Version " '​{print $2}' | awk -F "​."​ '​{print $1}'`
 +    if major_system_version.to_i < 9 
 +    # 10.4 or earlier
 +        volume_name = `diskutil info #{p.chomp} | grep "​Volume Name:" | awk -F "​Volume Name:        " '​{print $2}'`
 +    else
 +    # 10.5 or later
 +         volume_name = `diskutil info -plist #{p.chomp} | grep -A 1 "<​key>​VolumeName</​key>"​ | tail -n 1 | awk -F "<​string>"​ '​{print $2}' | awk -F "</​string>"​ '​{print $1}'​` ​      
 +     end
 +        if volume_name.chomp.to_s.empty?​
 +            new_partition = {"#​{p.chomp}"​ => nil}
 +        else
 +            new_partition = {"#​{p.chomp}"​ => "#​{volume_name.chomp}"​}
 +        end
 +        $disk_hash = $disk_hash.merge(new_partition)  ​
 +    }
 +}
 +
 +
 +# Find the device from the volume name (global varible)
 +def get_device
 +    if $disk_hash.has_value?​ $volume_name_to_mount
 +        device_to_mount = $disk_hash.key $volume_name_to_mount.to_s
 +        return device_to_mount
 +    else
 +        puts "​Volume is not available."​
 +        return nil
 +    end
 +end
 +
 +# check if the device is mounted
 +def is_device_mounted (device_to_mount)
 +    # find the first disk containing a volume with a matching name
 +    mount_point = `diskutil info -plist #​{device_to_mount[0]} | grep -A 1 -i MountPoint | tail -1 | awk -F "<​string>"​ '​{print $2}' | awk -F "</​string>"​ '​{print $1}'`
 +    if mount_point.chomp == ""​ then
 +        return false
 +    else
 +        return true
 +    end
 +end
 +
 +
 +# mount the device
 +def mount_first_volume_with_name
 +    device_to_mount = get_device
 +    if device_to_mount != nil 
 +        if ( (is_device_mounted(device_to_mount)) == false ) 
 +            device_mounted = `diskutil mount #​{device_to_mount} 1>/​dev/​null 2>&​1>/​dev/​null`
 +            if device_mounted.to_i == 0 
 +                # puts "​device already mounted."​
 +                return 0
 +            else
 +                return -1
 +            end
 +        end
 +    else
 +        return -1
 +    end
 +end
 +
 +# Pull the name of the volume to mount from the command line
 +if ARGV.length == 1
 +    name_of_volume_to_mount = ARGV[0].to_s.chomp
 +else
 +    puts "Usage : /​path/​to/​script/​ \"<​volume_name>​\""​
 +    exit -1
 +end
 +
 +# Tell this system to mount the disk
 +$volume_name_to_mount=name_of_volume_to_mount
 +result = mount_first_volume_with_name
 +exit result
 +
 +
 +</​file>​