Search code examples
pythonshellxonsh

Xonsh and rsync command


I have a test folder like this:

[20/01/3|2:08:12][samuel@localhost:/tmp]
>>> ls test1
1.txt  2.txt  3.txt  4.txt  5.txt

in a normal bash/zsh shell this is the output of the command

>>> rsync -avz --exclude="2.txt" --dry-run test1/ test2/
sending incremental file list
./
1.txt
3.txt
4.txt
5.txt

sent 138 bytes  received 31 bytes  338.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)
[20/01/3|2:10:42][samuel@localhost:/tmp]

but in a xonsh shell, this is the output

samuel@localhost /tmp $ rsync -avz --exclude="2.txt" --dry-run test1/ test2/                                                            
sending incremental file list
./
1.txt
2.txt
3.txt
4.txt
5.txt

sent 156 bytes  received 34 bytes  380.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)
samuel@localhost /tmp $

I try changing also with single apex, but result is the same.

Can anyone explain me where this simple command wrongs ??

My xonsh version is 0.9.11, but I test also with 0.9.13


Solution

  • Short answers:

    • remove equal sign i.e. --exclude "2.txt"
    • or remove quotes i.e. --exclude=2.txt
    • or use python substitution i.e. --exclude=@("2.txt")
    • or run macro call without any changes of the command i.e. bash -c! find ...

    Detailed answer:

    To understand the difference try to trace the command in bash and in xonsh.

    Bash:

    set -x
    rsync -avz --exclude="2.txt" --dry-run test1/ test2/
    # + rsync -avz --exclude=2.txt --dry-run test1/ test2/
    

    Xonsh:

    $XONSH_TRACE_SUBPROC=True
    rsync -avz --exclude="2.txt" --dry-run test1/ test2/
    # (['rsync', '-avz', '--exclude="2.txt"', '--dry-run', 'test1/', 'test2/'],)
    

    Here you can see the difference: bash removed quotes for the argument because quotes have special meaning in bash but xonsh leave them in the argument.

    To make it works you can remove quotes OR pass the filename using python substitution in xonsh:

    rsync -avz --exclude=2.txt --dry-run test1/ test2/
    rsync -avz --exclude=@("2.txt") --dry-run test1/ test2/
    

    Another way is to use the xonsh macro command and just run bash line as is:

    bash -c! rsync -avz --exclude="2.txt" --dry-run test1/ test2/
    

    To simplify this approach there is xontrib-sh extension that allows just add the ! sign before the command:

    ! rsync -avz --exclude="2.txt" --dry-run test1/ test2/
    

    Also: