You are not logged in.

#1 2016-01-21 15:27:52

drcouzelis
Member
From: Connecticut, USA
Registered: 2009-11-09
Posts: 4,092
Website

rsync trailing slash behaviour

I love rsync to death, but the trailing slash niggle kills me every time. sad Why can't these differences:

# Actual rsync difference!
rsync -a source  dest/
rsync -a source/ dest/

just be handled like this:

# Imaginary wishful thinking!
rsync -a source/  dest/
rsync -a source/* dest/

You know, like every other Linux application?

Offline

#2 2016-01-21 16:23:52

alphaniner
Member
From: Ancapistan
Registered: 2010-07-12
Posts: 2,810

Re: rsync trailing slash behaviour

Dunno about you, but that gets me mostly because I instinctively use tab completion. I wonder if it's possible to program auto-completion to not place trailing slashes just in this one case?


But whether the Constitution really be one thing, or another, this much is certain - that it has either authorized such a government as we have had, or has been powerless to prevent it. In either case, it is unfit to exist.
-Lysander Spooner

Offline

#3 2016-01-22 04:37:48

x33a
Forum Fellow
Registered: 2009-08-15
Posts: 4,587

Re: rsync trailing slash behaviour

alphaniner wrote:

Dunno about you, but that gets me mostly because I instinctively use tab completion.

Exactly the case with me. Then I have to press backspace and remove the trailing slash...

Offline

#4 2016-01-22 13:38:31

respiranto
Member
Registered: 2015-05-15
Posts: 479
Website

Re: rsync trailing slash behaviour

alphaniner wrote:

I wonder if it's possible to program auto-completion to not place trailing slashes just in this one case?

It is, though it has a notable drawback:
If you want to autocomplete a higher-level directory first, it would have to be completed without slash also. It could be added upon a subsequent tab, however that somehow misses the purpose of minimizing keypresses.
Furthermore, whenever you write (bash-)completion on your own*, it will complete full words, that is, upon double-tab, you will get a list of the full paths of possible completions, not only of the last word. Unless I have missed something.

* more precisely, whenever you write bash-completion scripts, that complete paths

Last edited by respiranto (2016-01-22 13:44:32)

Offline

#5 2016-01-22 14:09:55

alphaniner
Member
From: Ancapistan
Registered: 2010-07-12
Posts: 2,810

Re: rsync trailing slash behaviour

You're saying "somedir/anotherdir/yadir" would require typing "some<tab><tab>ano<tab><tab>ya<tab>" or "some<tab>/ano<tab>/ya<tab>" right? I wouldn't mind that, though it is admittedly a bit much to deal with the quirk of one program.

OTOH, in at least one live linux I've used that defaulted to zsh (sysresc and/or archiso), one <tab> will produce the trailing slash, but if the next key pressed is <space> the slash automagically disappears.

Last edited by alphaniner (2016-01-22 14:11:18)


But whether the Constitution really be one thing, or another, this much is certain - that it has either authorized such a government as we have had, or has been powerless to prevent it. In either case, it is unfit to exist.
-Lysander Spooner

Offline

#6 2016-01-22 14:11:32

respiranto
Member
Registered: 2015-05-15
Posts: 479
Website

Re: rsync trailing slash behaviour

alphaniner wrote:

You're saying "somedir/anotherdir/yadir" would require typing "some<tab><tab>ano<tab><tab>ya<tab>" or "some<tab>/ano<tab>/ya<tab>" right? I wouldn't mind that, though it is admittedly a bit much to deal with the quirk of one program.

Exactly.

OTOH, there's zsh. In at least one live linux I've used (sysresc and/or archiso), one <tab> will produce the trailing slash, but if the next key pressed is <space> the slash automagically disappears.

I did not think of that - It should also be possible to implement in bash.
I might have a look at rsync's bash-completion script and look for a way to to so.

EDIT: Sorry, I somehow mixed up some things. Obviously bash completion cannot handle this, because it does not act but upon a tab-keypress.

Last edited by respiranto (2016-01-22 15:59:54)

Offline

#7 2016-01-22 16:57:40

respiranto
Member
Registered: 2015-05-15
Posts: 479
Website

Re: rsync trailing slash behaviour

Continuing to hijack this thread, I have implemented what I initially suggested:

# bash completion for rsync                                -*- shell-script -*-
# - modified to not autocomplete the slashes of directory names

_rsync()
{
    local cur prev words cword split
    _init_completion -s -n : || return

    _expand || return 0

    case $prev in
        --config|--password-file|--include-from|--exclude-from|--files-from|\
        --log-file|--write-batch|--only-write-batch|--read-batch)
            compopt +o nospace
            _filedir
            return 0
            ;;
        -T|--temp-dir|--compare-dest|--backup-dir|--partial-dir|--copy-dest|\
        --link-dest)
            compopt +o nospace
            _filedir -d
            return 0
            ;;
        -e|--rsh)
            compopt +o nospace
            COMPREPLY=( $( compgen -W 'rsh ssh' -- "$cur" ) )
            return 0
            ;;
        --compress-level)
            compopt +o nospace
            COMPREPLY=( $( compgen -W '{1..9}' -- "$cur" ) )
            return 0
            ;;
    esac

    $split && return 0

    case $cur in
        -*)
            COMPREPLY=( $( compgen -W '--verbose --quiet --no-motd --checksum
                --archive --recursive --relative --no-implied-dirs
                --backup --backup-dir= --suffix= --update --inplace --append
                --append-verify --dirs --old-dirs --links --copy-links
                --copy-unsafe-links --safe-links --copy-dirlinks
                --keep-dirlinks --hard-links --perms --executability --chmod=
                --acls --xattrs --owner --group --devices --copy-devices
                --specials --times --omit-dir-times --super --fake-super
                --sparse --dry-run --whole-file --no-whole-file
                --one-file-system --block-size= --rsh= --rsync-path=
                --existing --ignore-existing --remove-source-files --delete
                --delete-before --delete-during --delete-delay --delete-after
                --delete-excluded --ignore-errors --force --max-delete=
                --max-size= --min-size= --partial --partial-dir=
                --delay-updates --prune-empty-dirs --numeric-ids --timeout=
                --contimeout= --ignore-times --size-only --modify-window=
                --temp-dir= --fuzzy --compare-dest= --copy-dest= --link-dest=
                --compress --compress-level= --skip-compress= --cvs-exclude
                --filter= --exclude= --exclude-from= --include= --include-from=
                --files-from= --from0 --protect-args --address= --port=
                --sockopts= --blocking-io --no-blocking-io --stats
                --8-bit-output --human-readable --progress --itemize-changes
                --out-format= --log-file= --log-file-format= --password-file=
                --list-only --bwlimit= --write-batch= --only-write-batch=
                --read-batch= --protocol= --iconv= --ipv4 --ipv6 --version
                --help --daemon --config= --no-detach' -- "$cur" ) )
            [[ $COMPREPLY == *= ]] || compopt +o nospace
            ;;
        *:*)
            # find which remote shell is used
            local i shell=ssh
            for (( i=1; i < cword; i++ )); do
                if [[ "${words[i]}" == -@(e|-rsh) ]]; then
                    shell=${words[i+1]}
                    break
                fi
            done
            if [[ $shell == ssh ]]
            then
                _xfunc ssh _scp_remote_files
                if test ${#COMPREPLY[@]} -eq 1 \
                    -a -z "${COMPREPLY[0]##*/}" \
                    && ! [[ "$cur/" =~ ":${COMPREPLY[0]}"$ ]]
                then
                    COMPREPLY=( ${COMPREPLY[@]%/} )
                fi
            fi
            ;;
        *)
            _known_hosts_real -c -a "$cur"
            _xfunc ssh _scp_local_files
            if test ${#COMPREPLY[@]} -eq 1 \
                -a -z "${COMPREPLY[0]##*/}" \
                -a "${COMPREPLY[0]}" != "$cur/"
            then
                COMPREPLY=( ${COMPREPLY[@]%/} )
            fi
            ;;
    esac

    return 0
} &&
complete -F _rsync -o nospace rsync

# ex: ts=4 sw=4 et filetype=sh

Note, that upon double-tab, the directories will be listed with slash, so they can still be differentiated from regular files.
If you want to use this script, simply save it at /etc/bash_completion.d/rsync.

Last edited by respiranto (2016-01-22 17:03:06)

Offline

#8 2016-01-23 00:28:37

MoSal
Member
Registered: 2015-09-23
Posts: 32

Re: rsync trailing slash behaviour

I wouldn't mess with default completions for this use-case. Using a shell function (or a stand-alone script if you want this to work everywhere) should suffice.

For ZSH users:

rsync_fixed() {
  rsync_args=($@)
  fixed_rsync_args=()

  for arg in ${rsync_args[@]}; do
    if [[ ${arg[-1]} == '/' ]]; then
      fixed_rsync_args+="${arg:0:-1}"
    else
      fixed_rsync_args+="${arg}"
    fi
  done

  rsync ${fixed_rsync_args[@]}
}

# We want ZSH completions for rsync to still work
compdef _rsync rsync_fixed

Offline

#9 2016-01-23 00:51:03

respiranto
Member
Registered: 2015-05-15
Posts: 479
Website

Re: rsync trailing slash behaviour

I don't see how changing the auto-completion can be seen as a risk.
Obviously it might be a good idea to track changes of the original script and one might even consider writing a script that uses the original one by calling `_xfunc' and only implements the added functionality by itself, though everything this script does is still - to complete, i.e. to help the user find a "solution".

Note that in contrast to your solution, the syntax of rsync{,_fixed} is kept untouched, which I believe is generally a good thing.

Offline

#10 2016-01-23 01:18:45

WorMzy
Forum Moderator
From: Scotland
Registered: 2010-06-16
Posts: 11,784
Website

Re: rsync trailing slash behaviour

I think this discussion has become more of a support discussion than a grr discussion. I'm going to split it off into it's own thread. Feel free to grr about this.


Sakura:-
Mobo: MSI MAG X570S TORPEDO MAX // Processor: AMD Ryzen 9 5950X @4.9GHz // GFX: AMD Radeon RX 5700 XT // RAM: 32GB (4x 8GB) Corsair DDR4 (@ 3000MHz) // Storage: 1x 3TB HDD, 6x 1TB SSD, 2x 120GB SSD, 1x 275GB M2 SSD

Making lemonade from lemons since 2015.

Offline

Board footer

Powered by FluxBB