1

Windows now has a build in openssh server, so we can use rsync to backup folders on windows pcs too. Problem is, that if I try to

rsync --relative -aqz --numeric-ids --delete-after -e 'ssh' 's2@black:C:\Users\s2\.gnupg' black

from a linux server, I end up with a local directory structure that looks like this:

black/
└── C:\Users\s2\.gnupg
    ├── crls.d
    │   └── DIR.txt
    ├── gpg-agent.conf
  [...]
    └── trustdb.gpg

so the root folder is a single folder named C:\Users\s2\.gnupg, and not three foldes like Users/s2/.gnupg. Is there a way to translate the windows path to a linux path so the backup makes sense?

0

you could merge the dir afterwards with

./script black

the script uses GNU find -print0 to loop over C: and create all directories, mv all files and delete old directories. only problem directories lose metadata like xattrs (but can easily overcome with few lines code for chown chcon etc)

script

find "$@" -depth -type d -iname 'C:\\*' -print0 | while IFS= read -r -d '' dir || [ "$dir" ]
  do
    path="${dir%/*}"
    dir="${dir##*/}"
    mkdir -p "$path/${dir//\\//}"
    find "$path/$dir" -maxdepth 1 -not -type d -exec mv {} "$path/${dir//\\//}" +
    rmdir "$path/$dir"
done

edit:

for mixed paths you need a little more code for merging. you can use cp -l instead mv for moving files via hard-links. metadata is preserved

script

#!/bin/bash
# or sh supporting read -d

# random name
tmp="${0##*/}_$(date '+%s')_tmp~"

# search for windows drive letters 'C:\' in 'black'
find -L "$@" -type d -iname '[A-Z]:\\*' -print0 | sort -z | while IFS= read -r -d '' dir || [ "$dir" ]
  do
    printf "'%s' -> " "$dir"

    # resolve symlinks
    dir="$(realpath "$dir")"

    path="${dir%/*}"
    dir="${dir##*/}"
    win="${dir%\\*}"
    nix="${dir##*\\}"

    printf "'%s'\n" "${dir//\\//}"

    # create linux directories
    mkdir -p "$path/${dir//\\//}"

    # move childs windows -> linux preserving metadata (via hard-links)
    find "$path/$dir" -mindepth 1 -maxdepth 1 \( -exec cp -abflPx {} "$path/${dir//\\//}" \; -a -exec rm -r {} \; \)

    # rename parent windows -> linux
    mkdir -p "$path/$tmp"
    mv "$path/$dir" "$path/$tmp/$nix"

    # copy parent metadata
    rsync -aAX "$path/$tmp/$nix" "$path/${win//\\//}"

    # delete windows directories
    rmdir "$path/$tmp/$nix" "$path/$tmp"
done

unfortunately it's much slower because find -exec \; and some unneccessary sort and echo

| improve this answer | |
-1

you need to mount /mnt/c/ first
or use cwrsync

| improve this answer | |
  • 1
    Can you explain a bit more? Why would mounting the C drive help?  What is cwrsync and how does one use it? – Scott Jul 31 at 16:08
  • self explaining - once mounted you can access paths with regular slash / i don't have Windows 10 to test but the link gives some instructions. i can copy & paste that or just delete that answer – alecxs Aug 1 at 20:41

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.