Files
q-tools/web/sshfs-mount
2025-04-22 13:12:33 +03:00

138 lines
3.6 KiB
Bash
Executable File

#!/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