Back up Files from Android with rsync and adb

This guide shows how to set up and use rsync in the adb (Android Debug Bridge) shell to transfer files between an Android device and a computer. rsync is a utility that is used to copy files and make backups on Unix and Linux systems. Because Android is based on Linux, it makes sense to use rsync for file and photo backups.

If you don't want to use the Android Debug Bridge (adb) shell, I also have another guide that runs rsync in the Termux terminal emulator app instead: Back up Files from Android with rsync and Termux

Created
June 16, 2023
A screenshot of a terminal window running the rsync client and a screenshot of Android showing a list of photos in the Files app

Overview

This guide runs an rsync binary on the Android device via the Android Debug Bridge (adb) shell. It starts rsync in daemon mode and forwards its port via adb to the computer. A computer can then run an rsync client and transfer files to and from the Android device.

This method can copy or backup files that are stored on the internal storage of the Android device and accessible in the Files app, such as photos, videos, and downloaded files. It can't back up Android applications or application data.

References

I have been using the steps described in this guide for years. I used information from these sources:

Prerequisites

In this guide, I use:

A Linux computer
I used a computer with Fedora Workstation 38 as the operating system, but it is possible to use another Linux distribution. The guide was tested on x86_64 and AArch64 computers. With some modifications, this guide may also work on macOS.
Android device
This device stores files and photos that I want to back up to the computer. It can also be used the other way around — as a destination for files from the computer. I used the Google Pixel 4a phone with Android 13.
Wi-Fi access point or USB cable
This will let us connect the Android device to the computer to open the adb shell. I used a home network with a Wi-Fi access point to set up a wireless debugging bridge between the Android device and the computer. Alternatively, the Android device can be connected to the computer with a USB cable.

Internet access is needed only to download the necessary software. The rsync file transfer itself uses adb and doesn't access the Internet.

Step 1: Install rsync on the Computer

Install rsync on the computer, if it isn't already installed. On Fedora Linux, rsync is most likely already preinstalled. If not, it can be installed with this command:

sudo dnf install rsync

Step 2: Build an rsync Binary for Android

I want to build an rsync binary that can be executed on the Android device. My Pixel phone runs a 64-bit ARM (AArch64) version of Android. Because Android is based on the Linux kernel, I will compile rsync as a statically-linked binary for the AArch64 Linux target.

Glibc can't properly build static binaries, and the Android NDK failed to compile the rsync binary because of incompatible data types. So I chose the musl standard library, which works without any issues.

My old Motorola phone used a 32-bit ARM version of Android. In that case, I followed the same instructions, except that I replaced the aarch64-linux-musl target triplet with armv7l-linux-musleabihf.

On the Linux computer, create a new container in which we will set up the build environment:

podman run -it --name musl-cross-builder --workdir /root fedora

Inside the container, install C/C++ build tools:

dnf -y --refresh upgrade
dnf -y install @c-development

Next, install the musl cross toolchain.

Download the latest rsync source code from https://rsync.samba.org/:

curl -L -O https://download.samba.org/pub/rsync/src/rsync-3.2.7.tar.gz
tar -xvf rsync-3.2.7.tar.gz
mv rsync-3.2.7 rsync-src

Compile the rsync source code into an AArch64 static executable binary:

export PATH="$PATH:$(realpath aarch64-linux-musl-cross)/bin"
cd rsync-src
TARGET=aarch64-linux-musl
./configure --disable-openssl --disable-xxhash --disable-zstd --disable-lz4 CFLAGS="-static" --host="$TARGET"
make
cd ..
mkdir -p compiled
cp rsync-src/rsync compiled/rsync-"$TARGET"

Strip debugging information from the rsync binary. Optionally, calculate and store a checksum.

cd compiled
"$TARGET"-strip rsync-"$TARGET"
sha256sum * > sha256sum.txt

Exit the container (type exit or press Ctrl+D). Copy the rsync binary and its checksum to the host OS:

mkdir ./rsync-musl
podman cp musl-cross-builder:/root/compiled ./rsync-musl/
A screenshot of the Files window on the Linux computer showing the compiled rsync binary

Step 3: Install Android SDK Platform Tools

Install Android SDK Platform Tools on the computer. We will use the Android Debug Bridge (adb) to connect to the Android device.

Step 4: Enable Debugging on the Android Device

Enable Wireless debugging on the Android device:

  1. Open Settings,
  2. select "About phone",
  3. tap "Build number" seven times to enable developer options.
  4. Go to the main Settings screen and select "System",
  5. open "Developer options",
  6. enable "Wireless debugging".

If the device doesn't support wireless debugging, use USB debugging instead.

A screenshot of Android with the Developer options menu open A screenshot of Android with the Wireless debugging menu open

Step 5: Connect to the Android Device

In the "Wireless debugging" menu on the Android device, select "Pair device with pairing code". It will show you an IP address and a port number as well as a Wi-Fi pairing code. The port number for pairing is different than the port number for connecting!

A screenshot of Android with the Pair with device screen in the Wireless debugging menu open

On the computer, use adb to pair and then connect the Android device:

adb pair ipaddr:pairingport
adb connect ipaddr:port

In my case, I ran:

adb pair 172.27.27.193:41653
adb connect 172.27.27.193:38889

Step 6: Start an rsync Daemon on the Android Device

Copy the rsync binary to the Android device:

adb push ./rsync-musl/compiled/rsync-aarch64-linux-musl /data/local/tmp/rsync

Forward port 60873 from the Android device to the Linux computer:

adb forward tcp:60873 tcp:60873

Open the adb shell:

adb shell

Once in the adb shell, make sure that the rsync binary on the Android device is executable. Create an rsync daemon config file and start the rsync daemon:

cd /data/local/tmp
chmod +x ./rsync
echo -e "address = 127.0.0.1\nport = 60873\n\n[root]\npath = /\nuse chroot = false\nread only = false" > rsyncd.conf
./rsync --daemon --no-detach --config=./rsyncd.conf --log-file=/proc/self/fd/2

Keep the terminal window with the adb shell open.

A screenshot of the terminal with an rsync daemon running in adb shell

Step 7: Back up Files with rsync

In another terminal window on the computer, run the rsync client and specify the forwarded port 60873 on the localhost as the source. The adb shell takes care of the data transfer from the localhost to the Android device.

I use this command to back up the internal storage of the Android device into a folder named Internal/ on my computer:

rsync -anv --delete --exclude='/Android' rsync://localhost:60873/root/storage/emulated/0/ Internal/

The command only prints the files that would be transferred. Remove the option n from -anv to actually transfer the files.

On my old Motorola phone, I used this command to copy files from the SD card to the Samsung SD card/ directory on my computer:

rsync -anv --delete --exclude='/Android' --exclude='/.android_secure' rsync://localhost:60873/root/storage/0000-0000/ Samsung\ SD\ card/

If the SD card is formatted with exFAT and rsync gives permission errors, replace -a with -vrtlD in the rsync command.

Don't forget to change the commands for your situation and remove the -n option to actually copy anything! You can swap the source and destination to copy files from the computer to the Android device.

Note that communication with the rsync daemon over the rsync:// protocol is not encrypted. This is not an issue for us because we configured the rsync daemon to listen on the localhost (127.0.0.1) of the Android device and forwarded the port to the computer via adb, which is hopefully secure.

A screenshot of a terminal window with a list of files printed by the rsync client

This is how I use rsync to periodically backup my files while checking that there is no issue with the files, in this order (paths omitted for brevity):

  1. First, do a dry run to see which files would be copied or deleted. This command only prints the files and doesn't copy or delete anything.

    rsync -anv --delete
  2. Then, copy only new files that don't exist in the destination. First, print the files, then copy them.

    rsync -anv --ignore-existing
    rsync -a --ignore-existing
  3. After that, update files that already exist in the destination.

    rsync -anv
    rsync -a
  4. Finally, delete files in the destination if they don't exist in the source.

    rsync -anv --delete
    rsync -a --delete
  5. By default, rsync uses the file size and the time stamps to detect if two files differ. To verify that the destination and source files are exactly the same bit-by-bit, I run:

    rsync -anvci --delete

Step 8: Disconnect the Android Device

When you are done, stop the rsync daemon in the terminal that runs the adb shell with Ctrl+C if it runs in the foreground or with the pkill rsync command if it runs in the background.

Then remove the rsync binary and the configuration file:

rm ./rsync ./rsyncd.conf

Exit the adb shell by typing exit or pressing Ctrl+D.

Disconnect the Android device from the computer:

adb forward --list
adb forward --remove tcp:60873
adb devices
adb disconnect ipaddr:port
adb kill-server

Don't forget to disable Wireless debugging and developer tools on the Android device!

Next Time Run

The next time you want to backup files from your Android device, you can skip the steps of building the rsync binary and installing the Android platform tools on the computer.