Rsync –list-only output not as expected

rsync

The rsync option --list-only appears to give output that isn't quite right. Here are my test files:

~/src$ ls
lrwxrwxrwx 1 michael michael 23 Sep  5 09:19 far_symlink -> /home/michael/Documents
-rw------- 1 michael michael  0 Sep  5 09:18 file
lrwxrwxrwx 1 michael michael  4 Sep  5 09:18 near_symlink -> file

I want a list of files that will be transferred, and I don't want symlinks, so I run this with --list-only:

~/src$ rsync -r --no-links --list-only ./ ~/dest
drwx------          4,096 2018/09/05 09:19:05 .
lrwxrwxrwx             23 2018/09/05 09:19:05 far_symlink
-rw-------              0 2018/09/05 09:18:15 file
lrwxrwxrwx              4 2018/09/05 09:18:28 near_symlink

It indicates the symlinks will be transferred, but this is not the case. If I actually do the transfer:

~/src$ ls ~/dest
drwx------  2 michael michael 4.0K 2018-09-05 09:39:16 .
drwxr-xr-x 30 michael michael 4.0K 2018-09-05 09:44:49 ..

~/src$ rsync -r --no-links ./ ~/dest
skipping non-regular file "far_symlink"
skipping non-regular file "near_symlink"

~/src$ ls ~/dest
drwxr-xr-x 30 michael michael 4.0K 2018-09-05 09:44:49 ..
-rw-------  1 michael michael    0 2018-09-05 09:48:10 file
drwx------  2 michael michael 4.0K 2018-09-05 09:48:10 .

The symlinks aren't sent.

So it feels like --list-only is not being truthful. Is there some way to get a list (without having to make contact with e.g. a remote ssh server) as to which files are actually to be transferred? What am I missing?

I'm on Ubuntu 18.04. Other details:

$ uname -a
Linux ubuntu 4.15.0-33-generic #36-Ubuntu SMP Wed Aug 15 16:00:05 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
$ rsync --version
rsync  version 3.1.2  protocol version 31
Capabilities:
64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
append, ACLs, xattrs, iconv, symtimes, prealloc

UPDATE: Please excuse my poor terminology. I understand the difference between what is a candidate to transfer vs. what will be transferred. My question is why are symlinks considered a candidate to transfer (and thereby being listed by--list-only) when they will obviously not be transferred regardless of the condition of the destination and they are (I thought) being explicitly excluded by no-links.

Best Answer

The --list-only option does not identify the files that will be transferred; it only identifies the files that are candidates for being transferred. You can see this here

touch aa bb cc; ln -s cc dd
rsync --list-only --no-links -a ?? /tmp
rsync -av ?? /tmp

rsync --list-only --no-links -a ?? /tmp

Output from last rsync

-rw-r--r--              0 2018/09/05 16:35:01 aa
-rw-r--r--              0 2018/09/05 16:35:01 bb
-rw-r--r--              0 2018/09/05 16:35:01 cc
lrwxrwxrwx              2 2018/09/05 16:35:01 dd -> cc

Consider the last rsync, where the files have already been transferred and remain unchanged on the source. If --list-only were to show files that needed to be transferred, nothing would be listed. However, it still shows the set of source files that need to be considered.

If you want to use context of the target to manage the set of files to be reported, use --dry-run --info=name

rsync --dry-run --info=name --archive --no-links ?? /tmp

Or, if you want a similar output to that produced by --list-only (notably omitting the entry type from the first character)

rsync --dry-run --info=name --out-format='%B%16l %t %f' --archive --no-links ?? /tmp

Initial output

skipping non-regular file "dd"
rw-r--r--               0 2018/09/05 16:42:30 aa
rw-r--r--               0 2018/09/05 16:42:30 bb
rw-r--r--               0 2018/09/05 16:42:30 cc

Subsequent output, once the files have been copied

skipping non-regular file "dd"
Related Question