如何将文件同步到安卓设备上的方法

如何连接我的安卓设备以进行音乐(或其他内容)的rsync同步?

2我建议编辑这部分内容,以准确解释导致错误信息的具体操作。(例如,如果是命令的输出结果,可以包含完整的命令) - Eliah Kagan
2或许有趣的应用:Syncopoli - DJCrashdummy
@DJCrashdummy,如果你把你的评论写成答案,我会点赞。 - guettli
@guettli 我只是以评论的形式写下这段话,因为 Syncopoli 目前只是一个 rsync 客户端。 - DJCrashdummy
无论使用何种方法运行rsync,我建议在计算机上创建一个热点,并将安卓设备连接到该热点。这样可以大大提高同步速度。 - Alexey
相关链接:https://stackoverflow.com/questions/55359419/can-rsync-be-used-to-transfer-files-from-android-client-to-linux-server-programm - undefined
10个回答

实际上,在MTP/USB上使用rsync很简单。首先需要注意的是,当GVFS挂载MTP时,它将在以下位置可用。你可以通过在图形文件浏览器(如thunar/nautilus等)中打开手机来强制进行此操作。
/run/user/$UID/gvfs

进去。假设你有一个MTP设备,这应该可以工作:
$ cd /run/user/$UID/gvfs/mtp*

找到你想要传输文件的位置,然后使用rsync将它们传输过去。
$ cd SanDisk\ SD\ card/Movies/

$ pwd # prints "/run/user/1000/gvfs/mtp:host=%5Busb%3A003%2C096%5D/SanDisk SD card/Movies"

$ rsync --verbose --progress --omit-dir-times --no-perms --recursive --inplace ~/Videos/ ./

Rsync选项

  • --inplace:我强烈建议使用--inplace,否则mtp可能会想要复制文件并将其重命名为旧文件。这可能导致文件被复制到SD卡两次:一次是为了将文件传输到SD卡,另一次是因为MTP驱动程序可能不支持(mv),它可能在底层使用(cp/rm)以确保安全。
  • 阅读rsync的man页面以了解--verbose--progress--recursive的描述,但它们都相当自说明。
  • --omit-dir-times--no-perms是必需的,因为mtp不支持这些功能。

3我添加了以下选项 --omit-dir-times --no-perms --ignore-existing。在通过MTP同步时,Rsync无法设置目录时间戳。我相当确定“无权限”是默认设置,但我喜欢明确指定它。忽略现有文件使其能够从上次中断的地方继续进行。 - Stephen Ostermiller
4为什么要使用--ignore-existing?这只会导致冗余的丢失。你可以始终使用--size-only,它只会将同步限制在目录列表而不是校验和上。我打算添加--omit-dir-times--no-perms,因为听起来很有用,而且我记得最后出现了一个关于权限的错误。 - Evan Carroll
Rsync在使用MTP时无法正确设置时间戳,所以如果没有使用--ignore-existing选项,它会尝试同步所有文件。我喜欢你提出的--size-only建议。下次我会尝试使用这个选项。 - Stephen Ostermiller
3我也在目标路径上使用尾部斜杠,这样我就不必在源路径上使用星号:~/Videos/ ./ - Stephen Ostermiller
我还不得不添加'--delete-after',以便让它删除我已经从计算机上的音乐文件夹中删除的文件。所以完整的命令是: rsync --verbose --progress --omit-dir-times --no-perms --recursive --inplace --ignore-existing --delete-after /home/user/MUSIC/ . - happyskeptic
注意:在使用“sudo”之前,这个命令是无效的。 - coderofsalvation
2我仍然在没有sudo的情况下收到"rsync: open /run/user/1000/gvfs/...失败: 操作不支持(95)"或者有sudo的情况下收到"rsync: ERROR: 无法检查目标 /run/user/1000/gvfs/... 权限被拒绝(13)"。有什么建议吗? - Torsten
这种做法打败了rsync:你正在将整个数据从Android设备传输到计算机! - Johan Boulé
这也适用于jmtpfs - 不要使用sudo挂载。 - naught101
对我来说,这只是创建文件夹而不是传输文件。 - Alexey
我在“复制”结束之前就投了赞同票。但是它无法复制!正如Torsten所说,只有在最后才会出现错误!现在这个网站不让我取消投票...我使用的是Android 6.0.1系统,没有进行Root,可能这就是问题所在。 - VeganEye
@JohanBoulé 我测试了这种方法,它的确比实际复制文件更快完成,因此节省了一些数据传输。 - qwr
我最终还是遇到了一堆错误,如rsync打开失败:操作不支持。不过所有的文件似乎都已经传输完成了... - qwr
1我们现在是2023年,但情况仍然一团糟。考虑到Android是基于Linux的,这对于几十年来Linux开发的巨大成就来说是一个巨大的悲剧,而谷歌却从中获利。Windows系统运行得无缝流畅,而Linux则需要尝试并可能会有幸运,或者花费几十年来调试错误。在我看来,他们应该有礼貌地优先考虑那些使他们的系统可用的数百万用户。 - user3342816

使用sshelper

我找到了这个解决方案:

  • 在设备上安装sshelper(无需root权限,可从Google Play商店下载)
  • 在我的局域网中,设备被称为“android”。但如果您无法为设备设置主机名,可以使用IP地址。

编辑本地ssh配置文件,以更改主机“android”的默认端口

.ssh/config
host android
    Port 2222
  • 在设备上启动sshelper。
  • 将Android设备连接到您的WLAN。

rsync -rvlc 音乐 android:SDCardLink/

更新

我更喜欢使用-rvlc而不是-a,因为设置权限和时间戳会导致很多警告。选项-c可以使第二次同步更快。

我更喜欢使用-rvl --size-only而不是-a,因为设置权限和时间戳会导致很多警告。选项--size-only可以使第二次同步更快。

不幸的是,音乐应用程序需要一些时间才能看到新文件。重新启动设备可以帮助解决问题。


15使用rsync与SSHelper的另一种方法,而无需修改.ssh/config文件:rsync -avz -e 'ssh -p 2222' Music android:SDCardLink/(http://stackoverflow.com/a/4630407/399105) - bmaupin
1@guettli 为什么在同步音乐文件时要使用 -c 校验和选项?这可能会显著减慢速度。 - EdiD
@EdiD 为什么-c会显著减慢速度?请解释一下。 - guettli
5@guettli 来自 rsync 手册:-c, --checksum。 如果没有使用此选项,rsync 将使用“快速检查”(默认情况下)检查发送方和接收方之间每个文件的大小和最后修改时间是否匹配。此选项将其更改为比较具有匹配大小的每个文件的 128 位校验和。生成校验和意味着双方都将花费大量磁盘 I/O 读取传输中文件中的所有数据,因此这可能会显著减慢速度。 - EdiD
@EdiD 好的,但据我所知,同步修改时间(mtimes)是不起作用的。我猜没有使用 -c 的 rsync 在这方面会遇到问题。 - guettli
4@guettli 我猜 --size-only 应该是最快的解决方案。然而,它不像 -c 那样安全。 - niels
2我使用了USB共享网络,并且传输速度更快。在运行SSH助手并显示IP 192.168.1.5后,以下命令对我有效,尽管每次可能会有所不同:rsync -avzhP --inplace --info=progress2 -e 'ssh -p 2222' 192.168.1.5:/storage/emulated/0/DCIM/Camera/ /home/username/path/to/pics/ - Organic Addict
我不知道在最新的sshelper中是否有什么新东西,但现在SDCardLink简单地变成了SDCard。所以你需要使用:rsync -rvl -e 'ssh -p 2222' ./WhatsApp/Media/ 192.168.2.102:SDCard/WhatsApp/Media/ - lechup
由于最近的Android操作系统更新破坏了SSHelper,此功能不再可用。 - Coder Guy
@JonathanNeufeld请您提供该特定更改的链接。 - guettli
@guettli 我没有链接,我直接给作者发了电子邮件。他说他正在努力收集更多关于这个问题的反馈,以找到根本原因。我找到了那个旧的线程,并发现当时给我的错误信息是“无法链接可执行文件“-bash”:找不到库“libTcpOptimizer.so”。他建议重新安装可能会起作用,但我没有那么幸运。在之前从未安装过Android 9之前的全新手机上可能会起作用。 - Coder Guy
这对我来说在Android 7.1.1上仍然有效,并且是adb pull的绝佳替代品,后者因各种原因而失败。 - lucidbrot
@JonathanNeufeld 我成功地在Android 10(Pixel 3a)上使用SSHelper 13.0和Debian stable(又名Buster)之间的wifi双向同步。 - RobertL

以上的方法都不完全符合我的需求。具体来说,OP提出的问题是:如何将我的音乐使用rsync同步到我的安卓手机上?嗯,我采纳了这些答案中的部分建议,并编写了自己的Bash脚本:
#!/bin/bash

echo "Starting rsync with Android."

src_dir="/home/joshua/Music"
dst_dir="/run/user/$UID/gvfs/mtp:host=OnePlus_HD1925_SERIAL/Internal shared storage"
rsync --progress \
      --human-readable \
      --omit-dir-times \
      --no-perms \
      --recursive \
      --inplace \
      --size-only \
      --exclude='*.jpg' \
      --exclude='*.JPG' \
      --exclude='*.jpeg' \
      --exclude='*.JPEG' \
      --exclude='*.png' \
      --exclude='*.bmp' \
      --exclude='*.txt' \
      --exclude='*.pdf' \
      --delete \
      "$src_dir" "$dst_dir"

echo "rsync operation is done. Enjoy the music :)"

我刚把这个放到了~/.local/bin里面,那是我放其他脚本的地方(你系统默认的PATH应该已经有这个目录了)。你只需要确保文件传输开启,并且存储实际上已经挂载好了再运行它。如果你不这样做也没关系:只是rsync会对你大喊大叫而已。
这个脚本:
- 考虑到安卓无法保留ext4风格的文件元数据 - 根据我的经验,使用size-only确实更快 - 排除了专辑封面和扫描图像,以免淹没你手机的文件系统 :) - 真正同步!当你从源头删除东西时,它会删除相应的内容,修复歌曲元数据并用正确的文件替换它,而不是保留两份副本。
此外,如果您选择这个答案是因为您喜欢--exclude标签,那么您可能还需要一种方法来清理手机上已经同步了大量不需要的图片。
# Remove all *.jpg and *.JPG from the current directory, recursively.
find . -iname *.jpg -exec rm {} \;

rsync备份适用于Android可配置为反向同步,即从Linux主机到Android设备。

而且,借助于LlamaLab Automate的帮助,可以在特定条件下自动配置Android设备进行rsync同步,例如:

  1. 在早上5点时,
  2. 当手机连接到特定的Wi-Fi网络时,以及
  3. 当手机正在充电时。

我正在寻找一种从安卓到NAS的rsync解决方案,用于备份图片。
Grsync,即rsync的图形化版本,运行得很
幸运的是,它也可以将文件同步到安卓设备。唯一的问题是它无法保留时间戳,因此所有传输的文件都会具有同步时刻的时间戳。
    sudo apt install android-file-transfer
    sudo apt-get install grsync

似乎在使用命令行从安卓同步到MTP时,我使用的一个关键字无效:当我在Grsync中选中“保留权限”、“保留所有者”和“保留组”时,没有任何文件被传输。默认的Grsync设置“保留时间”、“冗长模式”和“显示传输进度”可以正常工作。 而在将文件同步到安卓时,应省略-t关键字:文件将被传输,但rsync将报错未保留时间戳。 以下为从安卓到命令行的Grsync输出信息:
    rsync -r -t -v --progress -s /run/user/1000/gvfs/mtp\:host\=%5Busb%3A001%2C013%5D/Micro\ SD/test /home/FREENAS/

Grsync命令行到安卓的输出:
   rsync -r -v --progress -s /home/FREENAS/test /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C013%5D/Micro\ SD/

我的安卓手机挂载点在哪里?是在run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C013%5D吗?

你为什么安装了android-file-transfer? - jarno

使用Termux

Termux将许多Linux命令行实用程序带到Android平台,包括rsyncopenssh

您可以在Android设备上设置SSH服务器,然后通过SSH使用rsync,前提是您的PC和Android设备都连接到同一个WLAN网络。

Termux Wiki清楚地解释了设置SSH使用rsync所需的步骤。

总之:

  1. 安装Termux

    • 安装Termux
    • 在Android设置中授予Termux文件系统访问权限(存储权限)
    • 打开Termux
    • 设置密码
      $ passwd
      新密码:
      重新输入新密码:
      新密码成功设置。
      
    • 更新软件包列表
      $ apt update
      
    • 可选地,也可以升级现有的软件包(这解决了我遇到的一个兼容性问题)
      $ apt upgrade
      
  2. 安装openssh

    • 安装openssh
      $ apt install openssh
      
    • 启动ssh守护进程
      $ sshd
      
      默认监听端口为8022
  3. 安装rsync

    $ apt install rsync
    


开始之前,你只需要:

  • Termux 上的用户名
    $ whoami
    u0_a223
    
  • Android 设备的 IP 地址
    $ ip -4 a | grep wlan0 | tail -1
        inet 192.168.1.101/16 brd 192.168.255.255 scope global wlan0
    
    在此情况下,它是 192.168.1.101
现在,你可以用rsync做几乎任何事情。例如,如果你想将PC上的~/Music目录复制到Android设备的/sdcard目录,你可以这样做:
$ rsync -e 'ssh -p 8022' -aP ~/Music u0_a223@192.168.1.101:/sdcard

在提示输入密码时,请输入您之前设置的密码。

谢谢。在安卓13(Galaxy-Note10-5G)上对我来说很有效。 - spawn
对于习惯使用终端的人来说,这是一个很好的解决方案,你还可以设置crond以固定频率进行备份。如果目标设备也是安卓系统,请确保在目标设备上设置crond,并运行termux-media-scan -r $source_folder来通知应用程序有新文件产生,例如触发Google相册同步到云端。 - undefined

我的两分钱:
在最近的设备上(我使用的是MIUI14),Termux只适用于集成存储和外部卡上的特定目录,或者需要有root权限的设备。
对我来说,仅仅通过在文件管理器中打开MTP设备来打开终端并不起作用(比如Thunar)。
尽管设备已经解锁并在文件管理器中打开,但是对于我来说,gvfs下的/run/...目录是空的。
我通过卸载MTP设备(使用文件管理器)然后重新挂载它(使用jmtpfs)来解决了这个问题。

我尝试过在MTP上使用rsync,但在我的情况下,速度非常慢。如果你想尝试一下,这是一个建议。 我的解决方案基于以下来源:

https://bbs.archlinux.org/viewtopic.php?id=261904

我使用的是Kubuntu,所以在/run/user/1000/gvfs/文件夹中没有MTP文件夹。 我下载了以下软件包:

https://li.nux.ro/download/nux/dextop/el7/x86_64/simple-mtpfs-0.2-3.el7.nux.x86_64.rpm

有一个在Kubuntu 20.04上运行的二进制文件。你可以在`bin`文件夹中找到它,并解压到一个文件夹中。 不幸的是,在Plasma上,可能需要杀死特定的进程才能挂载设备。然后你可以使用`fuser`命令。 首先,你需要用`lsusb`命令找到你的设备:
$ lsusb
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 8087:0a2a Intel Corp. Bluetooth wireless interface
Bus 001 Device 011: ID 2717:ff48 Xiaomi Inc. Mi/Redmi series (MTP + ADB)
Bus 001 Device 003: ID 04f2:b3fd Chicony Electronics Co., Ltd HD WebCam (Asus N-series)
Bus 001 Device 006: ID 04fc:05d8 Sunplus Technology Co., Ltd Wireless keyboard/mouse
Bus 001 Device 004: ID 1bcf:08a0 Sunplus Innovation Technology Inc. Gaming mouse [Philips SPK9304]
Bus 001 Device 002: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

在这里,我们需要复制小米设备的MAC地址2717:ff48。 运行以下代码,并将2717:ff48替换为您设备的MAC地址:
DATA=`lsusb | grep '2717:ff48'`
echo $DATA
# Reading the bus number:
BUS=`echo ${DATA:4:3}`
# Reading the device number:
DEV=`echo ${DATA:15:3}`
# Killing the process which is using the device (if any)
fuser -k /dev/bus/usb/$BUS/$DEV

然后,您可以运行二进制文件并指定挂载文件夹的路径:
./simple-mtpfs --device 1 /tmp/xiaomi

然而,由于速度实在太慢,我只好放弃了,使用了一个读卡器,将文件从本地文件夹同步到了USB设备上。也许,这是最简单的选择。 对我来说,这是最佳的选择,因为目标文件夹中有一些需要删除的文件,并且为了延长SD卡的使用寿命,在不必要的情况下最好不要删除或创建新文件。

即使在使用其他mtp-fs程序时,使用设备部分终止进程也是有用的。我正在使用Android文件传输。它工作得很好,但有时无法挂载设备,因为KDE/Gnome先占用了设备。当发生这种情况时,您在这里提到的步骤非常有用。谢谢。 - Ananth Pattabiraman

我知道OP想要使用rsync,但如果目的是同步目录,我强烈推荐使用syncthing。很多好处:

  • 它将持续运行,无需定期启动;
  • 它可以同时将多个不同文件夹同步到多个不同设备;
  • 你可以将syncthing作为手机备份解决方案的一部分,包括两个步骤:(1)将手机上的所有重要数据同步到外部主机上,(2)在该主机上设置备份解决方案。

我个人会将我拥有的任何设备上的重要数据同步到至少另一台设备,可能是两台,位于物理上不同的地方;这些设备中至少有一台具有Raid硬盘;然后我在其中一台设备上添加snapper,以保留所有文件的旧版本;或者你可以使用syncthing的一个功能来实现相同的结果。

最后要提醒一点。如果你的某个设备空间不足,该设备将停止同步,但你不会收到任何错误提示,所以你应该定期检查。如果你使用snapper,很容易填满磁盘,所以请谨慎操作。

foldersync 应用程序可以使用 SFTP 协议,并且非常可配置。运行得非常顺畅。