me encontré con la necesidad de sincronizar mi música a mi celular Android. antes usaba Syncthing, que funciona, pero puede (ab)usar bastante batería (¡no es tan terrible igual! creo que el problema es la cantidad de datos que estaba sincronizando)

adb (“Android Development Bridge”, puente para desarrollo androide) es el programa que deja ejecutar comandos y otras cosas al celular conectado. está hecho, como el nombre lo dice, para desarrollo de aplicaciones androide, pero sirve para muchas otras cosas. permite hacer cosas que directamente no son posibles sin el uso de adb, a veces.

el método “estándar” para transferir archivos por USB a un android es un protocolo que se llama MTP. el resumen de este protocolo es que es lento y funciona mal (en mi experienciaa), aunque en versiones anteriores había otro método que era USB mass storage; básicamente el celular actuaba como un pendrive. andaba bien, pero creo que tenía riesgo de corrupción de datos.

adb tiene un comando que es adb push, que permite enviar archivos al celular. funciona bien para cosas básicas, pero cuando sincronizas música, copia las cosas aunque ya estén en el celular (entonces, si tenés una librería grande de música va a estar mil años cada vez que sincronizes). por suerte hay una opción que es --sync, que solo copia los archivos modificados. no se bien como adivina si se modificó o no, pero lo hace mal, ya que muchas veces me copió cosas que ya estaban, resultando en que tarde mucho más todo.

eso me llevó a buscar otra opción. para copiar archivos a servidores remotos, generalmente uso rsync, por que está disponible para casi todo, es muy flexible, es sencillo de usar y es estable. sin embargo, rsync por defecto va por una conexión SSH (el protocolo para conectarse a servidores remotos de forma segura) o por el protocolo de rsync mismo, que requiere un servidor especifico de rsync en el servidor remoto. vi varios tutoriales de como creaban un servidor de rsync dentro del celular y lo usaban para copiar cosas, pero por lo que entendí esto era solo a través de WiFi, que generalmente es más lento o inestable, y tenés que ir a descubrir la dirección IP del celu, etc.

eso me llevó a intentar hacer funcionar rsync vía adb. SSH esencialmente hace que puedas tener una terminal en un servidor remoto, y adb shell hace lo mismo pero con el celular. entonces, logré hacerle pensar a rsync que se conectaba por SSH al celular, aunque realmente se conecta por adb shell.

mi primer intento fue hacer rsync --rsh='adb shell' <el resto del comando> usuarix@ningúnlugar:carpeta_destino. --rsh le dice a rsync que use este comando para hacer ssh en vez de el defecto. puse usuarix y ningúnlugar por que no se está conectando a un servidor al que autenticarse, sino al celular que no requiere poner credenciales.

el problema es que rsync pasa parámetros que adb shell no entiende (por que está hecho para funcionar en SSH), pero no me importan por que son los de decirle a “SSH” a donde conectarse (-l usuarix -4 ningúnlugar, -l dice a que usuarix conectarse, -4 dice conectarse por IPv4). el truco es crear un script que descarte estos parámetros, pero dejando el resto que es el comando rsync que corre en el “servidor remoto” para transferir los archivos.

teniendo esto en cuenta, hice este script:

#!/bin/sh
echo Comando real: "$@" >> /dev/stderr
exec adb shell $(echo "$@" | sed --expression='s/^.*rsync/rsync/')

el sed pasa todos los argumentos ($@) pero ignorando todo lo que hay hasta el rsync, y reemplazandolo por solo rsync.1 también muestro el comando real en pantalla para tenerlo encuenta, sin embargo lo mando a stderr para que rsync no lo detecte como algo que dijo el rsync remoto.

solo hace falta darle permisos de ejecución al script y correr rsync con él:

$ chmod +x falso_ssh
$ rsync -uvrP -e './falso_ssh' ~/Music/* usuarix@ningúnlugar:/storage/TARJETA_SD/Music/
  • -u solo manda los archivos que no están (como --sync)
  • -v muestra que archivo se está transmitiendo
  • -r manda carpetas enteras (álbumes)
  • -P muestra la velocidad a la que se está transmitiendo
  1. este script fue editado ya que antes se hacía de una manera que se rompía fácil.