domingo, julio 12, 2015

Mandar comandos a la raspberry pi desde Android

Una cosa que quería hacer y no encontraba el momento de dedicarle tiempo era tener una aplicación en Android que mande comandos por ssh a la raspberry pi. En principio es bastante sencillo y hay bastantes aplicaciones que lo hacen (la mejor que he encontrado es Far Commander) pero no lograba que funcionaran cosas como apagarla o reiniciarla.

Estas aplicaciones son muy sencillas, básicamente te permiten configurar un botón que cuando lo pulsas se conecta por ssh y ejecuta el comando configurado. El tema es que si abría una sesión ssh también desde Android la cosa funcionaba bien. Como digo llevo bastante tiempo con este problema y por fin he encontrado un rato para resolverlo.

El problema es que estos programas usan ssh de una forma muy particular que se llama non interactive shell. Esto es, en lugar de hacer:

alejandro@DNC:~$ ssh pi@192.168.0.101
pi@192.168.0.101's password:
pi@raspbmc:~$ comando


Hace esto:

alejandro@DNC:~$ ssh pi@192.168.0.101 'comando'

Es decir, usa una función de ssh de lanzar un comando directamente en lugar de iniciar sesión, esperar al shell y lanzar el comando. Esto no sería nada del otro mundo si no fuera porque 'sudo shutdown' no funciona así:

alejandro@DNC:~$ ssh pi@192.168.0.101 'sudo shutdown -h now'
pi@192.168.0.101's password:
sudo: shutdown: command not found

¿Cómo que 'command not found'? Ahí obtuve mi primera pista. Y descubrí esto:

alejandro@DNC:~$ ssh pi@192.168.0.101
pi@192.168.0.101's password:
pi@raspbmc:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/opt/vc/bin:/home/pi/.xbmc-current/xbmc-bin/bin


alejandro@DNC:~$ ssh pi@192.168.0.101 'echo $PATH'
pi@192.168.0.101's password:
/usr/bin:/bin

Es decir, el PATH es distinto si estoy en la shell interactiva o si lanzo el comando directamente por ssh que es lo que hacen estos programas de Android que ejecutan comandos remotos.

La solución es fácil, basta con especificar el path. Donde antes ponía 'sudo shutdown -h now' ahora hay que poner 'sudo /sbin/shutdown -h now' y funciona a la perfección. Sé que podría haber toqueteado el .bashrc o .profiles para lograr que las non interactive shell pero he preferido no hacerlo por tres motivos:

1) La solución que he encontrado es sencilla, funciona y no tengo que seguir investigando cómo hacerlo
2) Si instalo de nuevo el sistema operativo de la raspberry pi no quiero tener que hacer mil cosas como modificar el .bashrc. Mi aplicación en Android funcionará directamente
3) Estuve mirando un poco  y no parecía fácil, puede que no sea sólo tocar el .bashrc y .profiles. Esto fue antes de darme cuenta de que podía incluir la ruta completa de shutdown

Espero que os resulte interesante.

No hay comentarios: