I'm regularly downloading files from a remote server, always from the same directory. So I wrote a custom function that I put in my bashrc:

download_from_myserver () {
    for file in "$@"
        rsync myserver:/home/pierre/downloads/"$file" .

Right now, the autocompletion works by default with files in the current directory. I would like to change the autocompletion so that bash automatically connects to the server via ssh and autocompletes with files that are in myserver:/home/pierre/downloads/.

In case I'm not being clear, here's an example: let's say I have my_file.txt in the remote directory, I want to be able to do this:

download_from_my_server my_fiTAB
download_from_my_server my_file.txt

How would I do this ?

Notes : I'm already using a password-less connection, rsync and scp autocomplete work well, that's not the issue. I'm using Ubuntu on both machines if that's important.

  • Nit: in "$@" is redundant in this case - for by default loops over the parameters.
    – l0b0
    May 15, 2013 at 10:55

1 Answer 1


Edit: Sliced it up some more.

You might find this useful, from Debian Administration: An introduction to bash completion.

Complete script: /some/location/my_ssh_autocomplete_script (only meant as a short starter):


    # For test:
    #local -a flist=("foo" "bar")
    #printf "%s " "${flist[@]}"
    # Or:
    ls /tmp

    # For live something in direction of:
    #ssh user@host 'ls /path/to/dir' <-- but not ls for other then dirty testing.

    local cur


    case "$cur" in
        COMPREPLY=( $( compgen -W '-h --help' -- "$cur" ) );;
        # This could be done nicer I guess:
        COMPREPLY=( $( compgen -W "$(_get_rsync_file_list)" -- "$cur" ) );;

    return 0

Download script /some/location/my_ssh_download_script:



download_from_myserver() {
    for file; do
        rsync "$server:$path/$file"

case "$1" in
        echo "Download files from '$server', path: '$path'" >&2
        exit 0;;

download_from_myserver "$@"

In .bash_aliases:

alias download_from_myserver='/some/location/my_ssh_download_script'

In .bash_completion:

# Source complete script:
if . "/some/location/my_ssh_autocomplete_script" >/dev/null 2>&1; then
    # Add complete function to download alias:
    complete -F _GetOptSSH download_from_myserver
  • "Double quote" every expansion, and anything that could contain a special character, eg. "$var", "$@", "${array[@]}", "$(command)". Use 'single quotes' to make something literal, eg. 'Costs $5 USD'. See <mywiki.wooledge.org/Quotes>, <mywiki.wooledge.org/Arguments> and <wiki.bash-hackers.org/syntax/words>. May 15, 2013 at 11:56
  • ls is a tool for interactively looking at file information. Its output is formatted for humans and will cause bugs in scripts. Use globs or find instead. Understand why: mywiki.wooledge.org/ParsingLs May 15, 2013 at 11:57
  • By convention, environment variables (PATH, EDITOR, SHELL, ...) and internal shell variables (BASH_VERSION, RANDOM, ...) are fully capitalized. All other variable names should be lowercase. Since variable names are case-sensitive, this convention avoids accidentally overriding environmental and internal variables. May 15, 2013 at 11:57
  • Thanks, this solution works really well! I did use find instead of ls, as pointed out by Rany Albeg Wein but that's the only thing I changed. And thank you for the link to debian-administration.org, I already read it but I wasn't handy enough to make good use of it :p May 15, 2013 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.