Ubuntu

如何在啟動時掛載 sshfs?

  • November 9, 2014

使用 NAS 盒作為 24/7 文件伺服器,我想使用 sshfs 從 Ubuntu 9.04 桌面連接到它。目前,我在桌面的 fstab 中有這一行:

sshfs#jldugger@storage:/mnt/HD_a2/    /mnt/storage    fuse   comment=sshfs,auto,users,exec,uid=1000,gid=1000,allow_other,reconnect,transform_symlinks,BatchMode=yes,fsname=sshfs#jldugger@storage/mnt/HD_a2/ 0 0

我可以確認它適用於 mount /mnt/storage。我需要的是一些在啟動時安裝它的方法,但是在建立網路連接之後。

目前,Ubuntu 中的 Upstart 不生成網路事件。相反,它呼叫傳統的 sysvinit。預設情況下 NetworkManager 已安裝並執行;它不是向新貴發出網路事件,而是包含一個 run-parts 調度程序 (/etc/NetworkManager/dispatcher.d/),它本身僅依賴於 ifupdown 的 run-parts 調度程序 (/etc/network/*.d/)。特別是您關心 /etc/network/if-up.d/ 和 /etc/network/if-down.d/

首先設置一個未加密的 ssh 密鑰對,這樣就可以在沒有提示的情況下掛載點。編寫一個腳本,將其放入 /etc/network/if-up.d/ 並使其可執行。以下是在 UbuntuForums 上發現的,對我來說已經足夠了:

#!/bin/sh
## http://ubuntuforums.org/showthread.php?t=430312
## The script will attempt to mount any fstab entry with an option
## "...,comment=$SELECTED_STRING,..."
## Use this to select specific sshfs mounts rather than all of them.
SELECTED_STRING="sshfs"

# Not for loopback
[ "$IFACE" != "lo" ] || exit 0

## define a number of useful functions

## returns true if input contains nothing but the digits 0-9, false otherwise
## so realy, more like isa_positive_integer 
isa_number () {
   ! echo $1 | egrep -q '[^0-9]'
   return $?
}

## returns true if the given uid or username is that of the current user
am_i () {
       [ "$1" = "`id -u`" ] || [ "$1" = "`id -un`" ]
}

## takes a username or uid and finds it in /etc/passwd
## echoes the name and returns true on success
## echoes nothing and returns false on failure 
user_from_uid () {
   if isa_number "$1"
   then
               # look for the corresponding name in /etc/passwd
       local IFS=":"
       while read name x uid the_rest
       do
               if [ "$1" = "$uid" ]
                       then 
                               echo "$name"
                               return 0
                       fi
       done </etc/passwd
   else
       # look for the username in /etc/passwd
       if grep -q "^${1}:" /etc/passwd
       then
               echo "$1"
               return 0
       fi
   fi
   # if nothing was found, return false
       return 1
}

## Parses a string of comma-separated fstab options and finds out the 
## username/uid assigned within them. 
## echoes the found username/uid and returns true if found
## echoes "root" and returns false if none found
uid_from_fs_opts () {
       local uid=`echo $1 | egrep -o 'uid=[^,]+'`
       if [ -z "$uid" ]; then
               # no uid was specified, so default is root
               echo "root"
               return 1
       else
               # delete the "uid=" at the beginning
               uid_length=`expr length $uid - 3`
               uid=`expr substr $uid 5 $uid_length`
               echo $uid
               return 0
       fi
}

# unmount all shares first
sh "/etc/network/if-down.d/umountsshfs"

while read fs mp type opts dump pass extra
do
   # check validity of line
   if [ -z "$pass" -o -n "$extra" -o "`expr substr ${fs}x 1 1`" = "#" ]; 
   then
       # line is invalid or a comment, so skip it
       continue

   # check if the line is a selected line
   elif echo $opts | grep -q "comment=$SELECTED_STRING"; then

       # get the uid of the mount
       mp_uid=`uid_from_fs_opts $opts`

       if am_i "$mp_uid"; then
                       # current user owns the mount, so mount it normally
                       { sh -c "mount $mp" && 
                               echo "$mp mounted as current user (`id -un`)" || 
                               echo "$mp failed to mount as current user (`id -un`)"; 
                       } &
               elif am_i root; then
                       # running as root, so sudo mount as user
                       if isa_number "$mp_uid"; then
                               # sudo wants a "#" sign icon front of a numeric uid
                               mp_uid="#$mp_uid"
                       fi 
                       { sudo -u "$mp_uid" sh -c "mount $mp" && 
                               echo "$mp mounted as $mp_uid" || 
                               echo "$mp failed to mount as $mp_uid"; 
                       } &
               else
                       # otherwise, don't try to mount another user's mount point
                       echo "Not attempting to mount $mp as other user $mp_uid"
:
                       echo "Not attempting to mount $mp as other user $mp_uid"
               fi
   fi
   # if not an sshfs line, do nothing
done </etc/fstab

wait

如果您有 wifi 或其他不可靠的連接,請將以下內容放在 /etc/network/if-down.d/ 中:

#!/bin/bash
# Not for loopback!
[ "$IFACE" != "lo" ] || exit 0

# comment this for testing
exec 1>/dev/null # squelch output for non-interactive

# umount all sshfs mounts
mounted=`grep 'fuse.sshfs\|sshfs#' /etc/mtab | awk '{ print $2 }'`
[ -n "$mounted" ] && { for mount in $mounted; do umount -l $mount; done; }

引用自:https://serverfault.com/questions/9605