#!/bin/bash _helpexit() { printf "Usage: %s [-u] [-nosave] [-nofollow] host [path] host can be from ssh config path is the remote path. Defaults to remote home. -u will unmount all FUSE.sshfs paths if no path given! -nosave will not use host key checking, nor save it anywhere. potentially dangerous. -nofollow disable symlinks following If you add 'host myhost # sshfs' line to ~/.ssh/config the entries will be listed first. Adding a remote path at the end: 'host myhost # sshfs /my/path' in ~/.ssh/config will use that path as default remotepath " "$( basename $0 )" _current_mounts exit 1 } _current_mounts() { echo Current mounts: cat /proc/mounts | grep fuse.sshfs | grep user_id=$( id -u ) | awk '{ print $1 " " $2 }' | sed "s,$HOME,~," | xargs printf "%15s %s\n" } _hosts() { { grep -Pi -e "^host ([^*]+)$" $HOME/.ssh/config | grep -e "#.sshfs"; grep -Pi -e "^host ([^*]+)$" $HOME/.ssh/config | grep -v -e "#.sshfs"; } | awk '{ print $2 }' | tr ' ' '\n' | grep -vie "^host$" -e "*" -e "^$"; } _menu() { _current_mounts choice=$( _hosts | \ smenu -t 1 -a c:0/2 i:3 -n 25 -m "Select server" \ -N -D n:1 i:1 ) echo $choice if [[ -z "$choice" ]]; then _helpexit fi host="$choice" } [[ -z "$1" ]] && _menu for (( i=1; i<=$#; i++ )); do [[ ${!i} = "-h" ]] && _helpexit [[ ${!i} = "--help" ]] && _helpexit done unmount=false nosave=false nofollow=false for (( i=1; i<=$#; i++ )); do [[ ${!i} = "-u" ]] && { unmount=true; continue; } [[ ${!i} = "-nosave" ]] && { nosave=true; continue; } [[ ${!i} = "-nofollow" ]] && { nofollow=true; continue; } if [[ -z "$host" ]]; then host="${!i}" else remotepath="${!i}" fi done mkdir -p ~/mnt valid_name=$( echo "$host" | sed -e 's/[^A-Za-z0-9._@-]//g') if [[ -z "$remotepath" ]]; then if [[ -e ~/.ssh/config ]]; then if grep -q ^"host $host # sshfs" ~/.ssh/config; then # pick only string after 'sshfs' remotepath=$( grep ^"host $host # sshfs" ~/.ssh/config | head -n 1 | sed "s/^host $host # sshfs //" ) fi fi fi path=:"${remotepath}" if [[ "$nosave" = true ]]; then NOSAVE="-o ssh_command='ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'" fi if [[ "$nofollow" = false ]]; then FOLLOW="-o follow_symlinks" fi if [[ "$unmount" = true ]]; then cd ~/mnt if [[ -n "$host" ]]; then echo Unmounting ~/mnt/$valid_name fusermount -u -z ~/mnt/$valid_name rmdir --ignore-fail-on-non-empty ~/mnt/$valid_name &>/dev/null else # no path, unmount all cat /proc/mounts | grep fuse.sshfs | grep user_id=$( id -u ) | awk '{ print $2 }' | while read dir; do echo Unmounting $dir fusermount -u -z "$dir" rmdir --ignore-fail-on-non-empty "$dir" &>/dev/null done fi exit fi if [[ -z "$host" ]]; then echo "No host given" _helpexit fi if [[ -d ~/mnt/"$valid_name" ]]; then device1=$( stat -c "%d" ~/mnt/"$valid_name" ) device2=$( stat -c "%d" ~/mnt/ ) else device1=valid device2=valid fi if [[ $device1 = $device2 ]]; then echo "Mounting $valid_name$path in ~/mnt/$valid_name" cd ~/mnt mkdir -p "$valid_name" eval sshfs \ -o reconnect \ -o uid=`id -u` \ -o gid=`id -g` \ -o ServerAliveInterval=45,ServerAliveCountMax=2 \ $NOSAVE \ $FOLLOW \ "$valid_name$path" "$valid_name" if [[ $? -gt 0 ]]; then rmdir "$valid_name" else df -h "$valid_name" fi else echo "~/mnt/$valid_name is already mounted" fi