39

How can I trigger an automount from the command line? By "automount" I don't mean fully automatic mounting, but getting a list of available devices and then selecting one and having it end up as /media/{user}/{diskid}. This functionality is provided by Nautilus or Thunar for example, but I can't seem to find a command line tool to trigger this kind of semi automatic mount.

pmount is the closest I have found, but seems to work by completely different mechanics underneath and makes devices show up as /media/sdf or something along the lines.

Grumbel
  • 4,729

6 Answers6

45

You can use:

udisksctl mount -b device_name

where device_name is the name of a storage device and should look something like /dev/sdb1.

Using lsblk or sudo fdisk -l command you can find out all storage devices attached to your system.

Pablo Bianchi
  • 15,657
Radu Rădeanu
  • 169,590
  • 2
    Tried that, that however leads to /media/{disk}, different from what Thunar or Nautilus would give. The udisksctl command provided by udisks2 however seems to do what I want. – Grumbel Sep 06 '13 at 14:02
  • 1
    udisksctl status will give a proper list of devices and work as user. fdisk -l not only requires root, it will also fail with GPT drives. cat /proc/partitions would be a better low-level way to get an idea of partitions available. – Grumbel Sep 06 '13 at 14:43
  • udiskctl is extremely useful for mounting image disk files into loop devices without root privileges, too! –  Aug 14 '17 at 22:05
  • Seems udisk was available until 14.04. – Pablo Bianchi Mar 16 '19 at 03:31
27

gio mount

gvfs is now listed as deprecated (2018) and you are advised to use 'gio' which is Gnome In Out and part of Glib. See Wikipedia.

For example, to auto-mount a second drive partition; create a bash script with executable permission to run at start-up with the following command:

gio mount -d /dev/sda2

If you are owner of the partition (see chown) you won't need sudo.

To mount an ISO file located for example on ~/ISOs:

gio mount "archive://file%3A%2F%2F%2Fhome%2Fpablo%2FISOs%2Fubuntu-18.04-desktop-amd64.iso"

You could URL encode the path with Python 3 and realpath (to concatenate to archive://:

python -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\"))" "file://$(realpath ubuntu-18.04-desktop-amd64.iso)"

This will mount on /run/user/$(id -u)/gvfs/ .

As an alternative gnome-disk-image-mounter will moount on /media/$USER/.

To unmount use gio mount -u /run/user/$(id -u)/gvfs/archive* (or /media/$USER/, depending the way you mounted).

udisksctl

Listing available devices:

udisksctl status

Mounting is done via:

udisksctl mount -b /dev/sdf

or

udisksctl mount -p block_devices/sdf

Unmounting is done via:

udisksctl unmount -b /dev/sdf

or

udisksctl unmount -p block_devices/sdf

The object-path can be found out by doing:

udisksctl dump

Object of type org.freedesktop.UDisks2.Block seem to be valid as object-patch, the /org/freedesktop/UDisks2/ prefix has to be cut from the path for udisksctl to accept them.

gvfs-mount

Listing available devices can be done with:

gvfs-mount --list

Mounting them can be done with:

gvfs-mount -d /dev/sdf

Unmounting is possible via:

gvfs-mount --unmount /media/user/01234567890

One remaining problem is that I have no idea how to use the gvfs-mount --list output in a mount command, as --list won't show block device names and trying to use the device names it prints in a mount will result in:

Error mounting location: volume doesn't implement mount

Conclusion

While both gvfs-mount and udisksctl will work for the tasks, their interface is impractical as they don't provide human readable status of the disks available, just an overly verbose info dump.

Pablo Bianchi
  • 15,657
Grumbel
  • 4,729
  • 1
    Could you extend your answer including how to mount an iso with gio mount? On 18.04 with Archive Mounter gio mount -l return Type: GDaemonMount but I couldn't mount it via CLI (maybe an issue?). – Pablo Bianchi Jan 17 '19 at 05:44
7

A simple solution that works as required (mounts to /media/{user}/{diskid}) except that it can not list devices but needs to be given the exact, case sensitive, volume label as argument $1

To mount:

DEVICE=$(findfs LABEL=$1) && udisksctl mount -b $DEVICE

To unmount:

DEVICE=$(findfs LABEL=$1) && udisksctl unmount -b $DEVICE
zvuk
  • 71
  • 1
  • 3
2

Just ran into the issue myself, and found the following solution:

udisksctl mount -b /dev/disk/by-labels/$LABEL

It will ask for the user password, even if it's you and you're already logged in.

komuta
  • 98
2

Script to mount drive - mount-menu.sh

The mount-menu.sh script allows you to select unmounted drives/partitions for mounting. To call the script use: sudo mount-menu.sh. This screen appears tailored to your unique machine environment:

mount-menu 1.png

  • Use arrow keys to select the partition and press Enter

The menu clears and leaves this information in your terminal:

=====================================================================
Mount Device:  /dev/nvme0n1p10
Mount Name:    /mnt/mount-menu.FPRAW
File System:   ext4
ID:            Ubuntu
RELEASE:       18.04
CODENAME:      bionic
DESCRIPTION:   Ubuntu 18.04.1 LTS
 Size  Used Avail Use%
  27G  7.9G   18G  32%

Now you can use: cd /mnt/mount-menu.FPRAW to access your external drive's partition.

Then you can use cd home/YOUR_NAME being mindful not to put a / in front of home. Should you use cd /home it would take you to your boot drive and out of the external drive.

mount-menu.sh script contents

To create the script open the terminal and type:

sudo -H gedit /usr/local/bin/mount-menu.sh

Then copy the code below and paste it into gedit. Save the file and exit gedit.

Now mark the file as executable using:

sudo chmod a+x /usr/local/bin/mount-menu.sh

Here's the script to copy:

#!/bin/bash

NAME: mount-menu.sh

PATH: /usr/local/bin

DESC: Select unmounted partition for mounting

DATE: May 9, 2018. Modified May 11, 2018.

$TERM variable may be missing when called via desktop shortcut

CurrentTERM=$(env | grep TERM) if [[ $CurrentTERM == "" ]] ; then notify-send --urgency=critical \ "$0 cannot be run from GUI without TERM environment variable." exit 1 fi

Must run as root

if [[ $(id -u) -ne 0 ]] ; then echo "Usage: sudo $0" ; exit 1 ; fi

Create unqique temporary file names

tmpMenu=$(mktemp /tmp/mount-menu.XXXXX) # Menu list tmpInfo=$(mktemp /tmp/mount-menu.XXXXX) # Mount Parition Info tmpWork=$(mktemp /tmp/mount-menu.XXXXX) # Work file MountName=$(mktemp -d /mnt/mount-menu.XXXXX) # Mount directory name

Function Cleanup () Removes temporary files

CleanUp () { [[ -f $tmpMenu ]] && rm -f $tmpMenu # If temporary files created [[ -f $tmpInfo ]] && rm -f $tmpInfo # at various program stages [[ -f $tmpWork ]] && rm -f $tmpWork # remove them before exiting. }

Mainline

lsblk -o NAME,FSTYPE,LABEL,SIZE,MOUNTPOINT > $tmpMenu

i=0 SPACES=' ' DoHeading=true AllPartsArr=() # All partitions.

Build whiptail menu tags ($i) and text ($Line) into array

while read -r Line; do if [[ $DoHeading == true ]] ; then DoHeading=false # First line is the heading. MenuText="$Line" # Heading for whiptail. FSTYPE_col="${Line%%FSTYPE}"
FSTYPE_col="${#FSTYPE_col}" # FS Type, ie ext4, ntfs, etc. MOUNTPOINT_col="${Line%%MOUNTPOINT
}" MOUNTPOINT_col="${#MOUNTPOINT_col}" # Required to ensure not mounted. continue fi

Line="$Line$SPACES"                     # Pad extra white space.
Line=${Line:0:74}                       # Truncate to 74 chars for menu.

AllPartsArr+=($i "$Line")               # Menu array entry = Tag# + Text.
(( i++ ))

done < $tmpMenu # Read next "lsblk" line.

Display whiptail menu in while loop until no errors, or escape,

or valid partion selection .

DefaultItem=0

while true ; do

# Call whiptail in loop to paint menu and get user selection
Choice=$(whiptail \
    --title &quot;Use arrow, page, home &amp; end keys. Tab toggle option&quot; \
    --backtitle &quot;Mount Partition&quot; \
    --ok-button &quot;Select unmounted partition&quot; \
    --cancel-button &quot;Exit&quot; \
    --notags \
    --default-item &quot;$DefaultItem&quot; \
    --menu &quot;$MenuText&quot; 24 80 16 \
    &quot;${AllPartsArr[@]}&quot; \
    2&gt;&amp;1 &gt;/dev/tty)

clear                                   # Clear screen.
if [[ $Choice == &quot;&quot; ]]; then            # Escape or dialog &quot;Exit&quot;.
    CleanUp
    exit 1;
 fi

DefaultItem=$Choice                     # whiptail start option.
ArrNdx=$(( $Choice * 2 + 1))            # Calculate array offset.
Line=&quot;${AllPartsArr[$ArrNdx]}&quot;          # Array entry into $Line.

# Validation - Don't wipe out Windows or Ubuntu 16.04:
# - Partition must be ext4 and cannot be mounted.

if [[ &quot;${Line:MOUNTPOINT_col:4}&quot; != &quot;    &quot; ]] ; then
    echo &quot;Partition is already mounted.&quot;
    read -p &quot;Press &lt;Enter&gt; to continue&quot;
    continue
fi

# Build &quot;/dev/Xxxxx&quot; FS name from &quot;├─Xxxxx&quot; menu line
MountDev=&quot;${Line%% *}&quot;
MountDev=/dev/&quot;${MountDev:2:999}&quot;

# Build File System Type
MountType=&quot;${Line:FSTYPE_col:999}&quot;
MountType=&quot;${MountType%% *}&quot;

break                                   # Validated: Break menu loop.

done # Loop while errors.

Mount partition

echo "" echo "=====================================================================" mount -t auto $MountDev $MountName

Display partition information.

echo "Mount Device=$MountDev" > $tmpInfo echo "Mount Name=$MountName" >> $tmpInfo echo "File System=$MountType" >> $tmpInfo

Build Mount information (the partition selected for cloning to)

LineCnt=$(ls $MountName | wc -l) if (( LineCnt > 2 )) ; then # More than /Lost+Found exist so it's not an empty partition. if [[ -f $MountName/etc/lsb-release ]] ; then cat $MountName/etc/lsb-release >> $tmpInfo else echo "No LSB-Release file on Partition." >> $tmpInfo fi else echo "Partition appears empty" >> $tmpInfo echo "/Lost+Found normal in empty partition" >> $tmpInfo echo "First two files/directories below:" >> $tmpInfo ls $MountName | head -n2 >> $tmpInfo fi

sed -i 's/DISTRIB_//g' $tmpInfo # Remove DISTRIB_ prefix. sed -i 's/=/:=/g' $tmpInfo # Change "=" to ":=" sed -i 's/"//g' $tmpInfo # Remove " around "Ubuntu 16.04...".

Align columns from "Xxxx:=Yyyy" to "Xxxx: Yyyy"

cat $tmpInfo | column -t -s '=' > $tmpWork cat $tmpWork > $tmpInfo

Mount device free bytes

df -h --output=size,used,avail,pcent "$MountDev" >> $tmpInfo

Display partition information.

cat $tmpInfo

CleanUp # Remove temporary files

exit 0


umount-menu.sh to Unmount Drives/Partitions

Repeat the file creation / execute bit marking process for the script umount-menu.sh. This script only unmounts drives / partitions that were mounted by mount-menu.sh. It has the same selection menu and completes with the message:

=====================================================================

/dev/nvme0n1p10 mounted on /mnt/mount-menu.FPRAW unmounted.

To call the script use: sudo umount-menu.sh

umount-menu.sh bash script:

!/bin/bash

NAME: umount-menu.sh

PATH: /usr/local/bin

DESC: Select mounted partition for unmounting

DATE: May 10, 2018. Modified May 11, 2018.

$TERM variable may be missing when called via desktop shortcut

CurrentTERM=$(env | grep TERM) if [[ $CurrentTERM == "" ]] ; then notify-send --urgency=critical \ "$0 cannot be run from GUI without TERM environment variable." exit 1 fi

Must run as root

if [[ $(id -u) -ne 0 ]] ; then echo "Usage: sudo $0" ; exit 1 ; fi

Create unqique temporary file names

tmpMenu=$(mktemp /mnt/mount-menu.XXXXX) # Menu list

Function Cleanup () Removes temporary files

CleanUp () { [[ -f "$tmpMenu" ]] && rm -f "$tmpMenu" # at various program stages }

Mainline

lsblk -o NAME,FSTYPE,LABEL,SIZE,MOUNTPOINT > "$tmpMenu"

i=0 SPACES=' ' DoHeading=true AllPartsArr=() # All partitions.

Build whiptail menu tags ($i) and text ($Line) into array

while read -r Line; do if [[ $DoHeading == true ]] ; then DoHeading=false # First line is the heading. MenuText="$Line" # Heading for whiptail. MOUNTPOINT_col="${Line%%MOUNTPOINT*}" MOUNTPOINT_col="${#MOUNTPOINT_col}" # Required to ensure mounted. continue fi

Line=&quot;$Line$SPACES&quot;                     # Pad extra white space.
Line=${Line:0:74}                       # Truncate to 74 chars for menu.

AllPartsArr+=($i &quot;$Line&quot;)               # Menu array entry = Tag# + Text.
(( i++ ))

done < "$tmpMenu" # Read next "lsblk" line.

Display whiptail menu in while loop until no errors, or escape,

or valid partion selection .

DefaultItem=0

while true ; do

# Call whiptail in loop to paint menu and get user selection
Choice=$(whiptail \
    --title &quot;Use arrow, page, home &amp; end keys. Tab toggle option&quot; \
    --backtitle &quot;Mount Partition&quot; \
    --ok-button &quot;Select unmounted partition&quot; \
    --cancel-button &quot;Exit&quot; \
    --notags \
    --default-item &quot;$DefaultItem&quot; \
    --menu &quot;$MenuText&quot; 24 80 16 \
    &quot;${AllPartsArr[@]}&quot; \
    2&gt;&amp;1 &gt;/dev/tty)

clear                                   # Clear screen.

if [[ $Choice == &quot;&quot; ]]; then            # Escape or dialog &quot;Exit&quot;.
    CleanUp
    exit 1;
 fi

DefaultItem=$Choice                     # whiptail start option.
ArrNdx=$(( $Choice * 2 + 1))            # Calculate array offset.
Line=&quot;${AllPartsArr[$ArrNdx]}&quot;          # Array entry into $Line.

if [[ &quot;${Line:MOUNTPOINT_col:15}&quot; != &quot;/mnt/mount-menu&quot; ]] ; then
    echo &quot;Only Partitions mounted by mount-menu.sh can be unounted.&quot;
    read -p &quot;Press &lt;Enter&gt; to continue&quot;
    continue
fi

# Build &quot;/dev/Xxxxx&quot; FS name from &quot;├─Xxxxx&quot; menu line
MountDev=&quot;${Line%% *}&quot;
MountDev=/dev/&quot;${MountDev:2:999}&quot;

# Build Mount Name
MountName=&quot;${Line:MOUNTPOINT_col:999}&quot;
MountName=&quot;${MountName%% *}&quot;

break                                   # Validated: Break menu loop.

done # Loop while errors.

Unmount partition

echo "" echo "=====================================================================" umount "$MountName" -l # Unmount the clone rm -d "$MountName" # Remove clone directory

echo $(tput bold) # Set to bold text echo $MountDev mounted on $MountName unmounted. echo $(tput sgr0) # Reset to normal text

CleanUp # Remove temporary files

exit 0

1

I wrote this Bash script to work around this problem, but be aware that I'm a scripting newbie. All suggestions welcome! Usage and description follow below the script.

#!/bin/bash
# umanage.sh
# 2014-05-05

BASEPATH="/media/$(whoami)/"
RESULTS=$(udisksctl dump | grep IdLabel | grep -c -i "$1")

case "$RESULTS" in

0 )     echo "Nothing found."
        ;;

1 )     DEVICELABEL=$(udisksctl dump | grep IdLabel | grep -i "$1" | cut -d ":" -f 2 | sed 's/^[ \t]*//')
        DEVICE=$(udisksctl dump | grep -i "IdLabel: \+$DEVICELABEL" -B 12 | grep " Device:" | cut -d ":" -f 2 | sed 's/^[ \t]*//')
        DEVICEPATH="$BASEPATH""$DEVICELABEL"

        if [[ -z $(mount | grep "$DEVICE") ]]
        then
                echo "Found unmounted $DEVICE partition."
                echo "Do you want to mount it in $DEVICEPATH?"
                select yn in "Mount" "Ignore"
                do
                        case $yn in
                        Mount )         udisksctl mount -b "$DEVICE"
                                        break
                                        ;;
                        Ignore )        exit
                                        ;;
                        esac
                done
        else
                echo "Found $DEVICE partition, currently mounted in $DEVICEPATH."
                echo "Do you want to unmount it?"
                select yn in "Unmount" "Ignore"
                do
                        case $yn in
                        Unmount )       udisksctl unmount -b "$DEVICE"
                                        break
                                        ;;
                        Ignore )        exit
                                        ;;
                        esac
                done
        fi
        ;;

* )     if [ $# -eq 0 ]
        then
                echo "No argument supplied"
        else
                echo "$RESULTS possible results. You may be looking for:"
                echo
                udisksctl dump | grep IdLabel | grep -i "$1" | cut -d ":" -f 2 | sed 's/^[ \t]*//' | sed '/^$/d'
                echo
                echo "Please refine your search."
        fi
        ;;

esac

Usage:

  • save the script as umanage.sh
  • make it executable: chmod +x umanage.sh
  • run it: ./umanage.sh YourDeviceLabel

The script accepts as an argument the label of the partition you want to mount and looks in the udisksctl dump for corresponding entries.

If a partition is found and it's not mounted, device name and path are shown and you're offered to mount the partition. The script searches for partial labels too, and it won't care about upper or lower case (useful when you don't remember the exact label).

./umanage.sh PASSPORT
Found unmounted /dev/sdf1 partition.
Do you want to mount it in /media/pixel/My Passport?
1) Mount
2) Ignore
#? 

If a partition is found and it's already mounted, you're offered to unmount it:

./umanage.sh passp
Found /dev/sdf1 partition, currently mounted in /media/open/My Passport.
Do you want to unmount it?
1) Unmount
2) Ignore
#?

If your argument matches more than a result, the script shows you the matching partition labels and asks you to refine the search:

./umanage.sh SS
2 possible results. You may be looking for:

SSD-9GB
My Passport

Please refine your search.
pixel
  • 27