Ssh – How to get information about remote directories mounted through sshfs

mountsshfs

If I mount a directory from a remote server on my local machine using sshfs, how can I find out such details as:

  • Whether any such mount is currently mounted;
  • The user who mounted it;
  • The remote and local directories;
  • The time it was mounted at.

Best Answer

If the remote directory is mounted, it will be listed in the output of mount. That contains most of the information you need:

$ mount -t fuse.sshfs 
terdon@123.456.7.8:/remote/path/dir/ on /home/terdon/foo type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=1001,group_id=1001)

With that in mind, you could write a little script that parses the output and gives you most of the details:

$ mount -t fuse.sshfs | 
    perl -ne '/.+?@(\S+?):(.+?)\s+on\s+(.+)\s+type.*user_id=(\d+)/; 
    print "Remote host: $1\nRemote dir: $2\nLocal dir: $3\nLocal user: $4\n"'
Remote host: 139.124.66.43
Remote dir: /cobelix/terdon/research/
Local dir: /home/terdon/haha
Local user: 1001

This can be made into a shell function or script, extended to show user name instead of UID and extracting the time from ps. This assumes you don't need milliseconds accuracy since the output of ps refers to when the command was launched and not necessarily when the mount operation ended.

sshfs_info(){
    mount -t fuse.sshfs | head -n1 |
    perl -ne '/.+?@(\S+?):(.+)(?= on\s+\/)(.+)\s+type.*user_id=(\d+)/; 
     print "Remote host: $1\nRemote dir: $2\nLocal dir: $3\nLocal user: " . 
     `grep  :1001: /etc/passwd | cut -d: -f1` '
    printf "Elapsed time: %s\n" $(ps -p $(pgrep -f sftp | head -n1) o etime=)
    }

If you add the function above to your shell's initialization file (e.g. ~/.bashrc for bash), you can then run:

$ sshfs_info
Remote host: 123.456.7.8
Remote dir: /remote/path/dir
Local dir: /home/terdon/foo
Local user: terdon
Elapsed time: 44:16

Note that this assumes only a single sftp instance is running. If you need to deal with multiple instances, use this one instead:

sshfs_info(){
## A counter, just to know whether a separator should be printed
c=0
## Get the mounts
mount -t fuse.sshfs | grep -oP '^.+?@\S+?:\K.+(?= on /)' |
# Iterate over them
    while read mount
    do
    ## Get the details of this mount. 
    mount | grep -w "$mount" |
        perl -ne '/.+?@(\S+?):(.+)\s+on\s+(.+)\s+type.*user_id=(\d+)/; 
              print "Remote host: $1\nRemote dir: $2\nLocal dir: $3\nLocal user: " . 
              `grep  :1001: /etc/passwd | cut -d: -f1` '
    printf "Elapsed time: %s\n" "$(ps -p $(pgrep -f "$mount") o etime=)"
    ## Increment the counter
    let c++;
    ## Separate the entries if more than one mount was found
    [[ $c > 0 ]] && echo "---"

    done
}

The output looks like:

$ sshfs_info 
Remote host: 123.456.7.8
Remote dir: /remote/path/foobar/
Local dir: /home/terdon/baz
Local user: terdon
Elapsed time:    01:53:26
---
Remote host: 123.456.7.8
Remote dir: /remote/path/foo/
Local dir: /home/terdon/bar
Local user: terdon
Elapsed time:    01:00:39
---
Remote host: 123.456.7.8
Remote dir: /remote/path/bar/
Local dir: /home/terdon/baz
Local user: terdon
Elapsed time:       53:57
---
Remote host: 123.456.7.8
Remote dir: /remote/path/ho on ho
Local dir: /home/terdon/a type of dir
Local user: terdon
Elapsed time:       44:24
---

As you can see in the example above, it can deal with directory names containing spaces as well.

Finally, note that this is not 100% portable. It should work on any system that has the GNU toolset (any Linux distribution, for example) but it won't work on non-GNU systems because it's using features specific to GNU grep.