Bash custom functions and autocompletion

To easily upload torrents files to my VPS I wrote a custom function I put in my .bashrc :

upload_torrents () {
    for file; do
        filename=$(basename "$file")
        extension="${filename##*.}"
        if [ $extension = 'torrent' ]
            then
                rsync -a --partial --progress "$file" mybox:/home/downloads/torrents/watch/
        else
            echo "$file"" is not a torrent"
        fi
    done
}

This function is pretty straightforward, it uploads all the torrent files passed in arguments. Using it I realized it was lacking something: I wanted the bash autocompletion to only propose the torrent files instead of all the files in the directory. I added the following snippet to my .bashrc and it did the trick (found here):

complete -f -X '!*.@(torrent)' upload_torrents

Now that we’ve uploaded the torrents, we need to download the files from the remote server to our local machine. Here is another custom function I wrote:

download_from_mybox () {
    for file; do
        rsync -a --partial --progress --bwlimit=500 mybox:/home/downloads/torrents/"$file" .
    done
}

Even simpler than the first one. How about adding autocompletion to this command? Obviously we need to complete using the list of files located on the remote server in /home/downloads/torrents/. I had quite a lot of difficulties trying to figure this one out and I finally asked the fine people of unix.stackexchange. Here is how I finally did it:

In /etc/bash_completion.d/, I created a download_from_my_box file containing the following:

#!/bin/bash

_get_rsync_file_list()
{
    ssh mybox "cd /home/downloads/torrents/pierre && find *"
}

_GetOptSSH()
{
    local cur

    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}

    case "$cur" in
    -*)
        COMPREPLY=( $( compgen -W "-h -l --help --list --" -- "$cur" ) );;
    *)
        local -a filelist=$(_get_rsync_file_list)
        COMPREPLY=( $( compgen -W "${filelist[@]}" -- "$cur" ) );;
    esac

    return 0
}

complete -F _GetOptSSH download_from_mybox

The case on $cur isn’t strictly necessary since I didn’t implement any option in my command but it’s good to know how to do it.

So that’s how you do custom remote autocompletion in bash! Pretty rad I know.

If you want to learn more on the matter, here is a very good article in two parts hosted on http://www.debian-administration.org

Quick edit before I post an article with the complete solution: this doesn’t work if you have spaces in your filenames/directories. I asked for help on the UnixStackExchange and got an awesome answer. I’m trying to find the time to implement a fully working solution and post it here.

About these ads

Tags: , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: