====== Termux ======
Emulatore terminale per Android e collezione di pacchetti GNU/Linux-like. Dopo aver installato l'emulatore è possibile installare con il comando **apt** diversi pacchetti con i tool da riga di comando più famosi (rsync, ssh, ecc.).
* **Fondamentali**
* **Termux** - Progamma terminale.
* **Termux:Widget** - Consente di creare un menu sul desktop per avviare script e task Termux (a pagamento sul Google Play Store, libero su F-Droid).
* **Termux:API** - Consente di accedere ad alcune API Android ad esempio per ottenere la posizione GPS, inviare SMS, ecc.
* **Opzionali**
* **Termux:Styling** - Consente di personalizzare l'aspetto del terminale con schemi di colori e font (a pagamento sul Google Play Store, libero su F-Droid). Per cambiare lo stile: long-press in una finestra di terminale, //Moore// => //Style//.
Il pacchetto Termux:Widget è particolarmente utile perché consente di aggiungere sul desktop un menu con un elenco di comandi eseguibili con un tap. Ogni voce di menu corrisponde ad uno script di shell installato in una apposita directory.
Essendo software open source, è disponibile anche la versione free su F-Droid. **ATTENZIONE**: la versione del Google Play Store e quella di F-Droid non sono compatibili tra loro (es. l'app Termux e l'app Termux Widget devono avere la stessa origine), perché sonon firmate con chiavi diverse e non possono installarsi nella stessa directory.
Dopo aver installato la app nell'ambiente Android, alla prima esecuzione, vengono scaricati da internet i **bootstrap packages**, cioè alcuni pacchetti che vengono scompattati nel **root filesystem** di Termux, cioè **/data/data/com.termux/files/**. Anche tutto ciò che verrà installato in seguito dal terminale verrà scaricata da internet e scompattato nel root filesystem.
===== Directory =====
^ /data/data/com.termux/files/ | Praticamente è il **root filesystem** per l'ambiente Termux. L'installazione di pacchetti aggiuntivi, script utente, ecc. avviene in questa directory. Eliminando i dati della app Termux (da //Impostazioni// => //App// => //Termux// => //Spazio di archiviazione//) si elimina il contenuto di questa directory, ripristinando l'ambiente Termux al suo default. |
^ .../files/usr/local/bin/ | Script e programmi utente, ai quali è necessario impostare il **mode 700**. |
^ .../files/home/.shortcuts/ | Ogni script installato in questa directory diviene una entry nel menu Termux Widget. |
^ .../files/home/.shortcuts/tasks/ | Come per la directory precedente, ma lo script viene eseguito in background, senza un terminale. |
^ .../files/home/.ssh/ | Configurazione ssh utente termux (chiave RSA pubblica/privata, ecc.) |
===== Gestione pacchetti =====
Per la gestione dei pacchetti si usa **pkg** (che è un wrapper di **apt**), ciò rende non necessario aggiornare periodicamente la lista dei pacchetti disponibili.
Ecco i comandi per avere la lista di tutti i pacchetti disponibili, per installare da repository e disinstallare un pacchetto, per vedere i pacchetti già installati:
pkg list-all
pkg install [package name]
pkg uninstall [package name]
pkg list-installed
Per aggiornare tutti i pacchetti installati:
pkg upgrade
Se si ha il file di un pacchetto da installare, si uilizza il tradizionale **dpkg** di derivazione Debian:
dpkg -i ./package.deb
==== Repository ====
I repository di pacchetti si aggiungono installando degli speciali pachetti **%%-repo%%**. Il repository principale è attivato installando il pacchetto **root-repo**,
==== Problemi con aggiornamento distribuzione ====
Quando si aggiorna la app Termux, è necessario aggiornare anche l'ambiente Termux, cioè tutti i pacchetti che sono stati installati nel filesystem /data/data/com.termux/files/.
Da qualche parte si dice che per l'aggiornamento dovrebbe essere sufficiente eseguire nel terminale come i comandi tradizionali Debian per l'aggiornamento: ''apt update'' seguito da ''apt dist-upgrade'', ma a noi è capitato di **rendere l'ambiente Termux non più funzionante**. Uno dei problemi era relativo all'aggiornamento del pacchetto essenziale **libandroid-support**, l'errore mostrato è:
E: This installation run will require temporarily removing the essential
package libandroid-support:aarch64 due to a Conflicts/Pre-Depends loop.
This is often bad, but if you really want to do it, activate the
APT::Force-LoopBreak option.
E: Internal Error, Could not early remove libandroid-support:aarch64 (2)
A quanto si apprende dal problema **[[https://github.com/termux/termux-packages/issues/4129|#4129]]**, pare che non ci sia una via semplice per uscire dal problema. Installando manualmente i pacchetti con **%%dpkg -i%%** siamo arrivati ad una situazione di non funzionamento totale (programma tar senza librerie necessarie, quindi impossibile spacchettare e installare nuovi pacchetti).
Si risolve cancellando i dati della app, il che significa sostanzialmente svuotare la cartella **/data/data/com.termux/files/** e quindi tutti i pacchetti installati e le personalizzazioni.
===== Pacchetti da installare =====
Si possono tutti installare con **pkg install** seguito dal nome del pacchetto.
* **openssh** Server ssh. Questo è il primo pacchetto da installare, usando una sessione Termux direttamente sullo schermo del dispositivo Android. Dopo aver installato questo sarà possibile **accedere più comodamente** al dispositivo da un comune PC, **via ssh**, sfruttando il port forward di ADB (vedia più avanti).
* **mc** **vim** **rsync** **wget** **file** **which** Sono i generici tool Unix, indispensabili.
* **python** Linguaggio di programmazione, alternativa agli script shell. FIXME C'è da verificare quanto siano più onerosi in termini computazionali rispetto agli script shell.
* **termux-api** Comandi per interfacciarsi con i servizi Android, ad esempio ''termux-location'' per accedere ai dati GPS, ''termux-camera-photo'' per scattare foto, ''termux-microphone-record'' per registrare audio, ecc.
* **figlet** Consente di creare scritte grandi in ASCII art, utili per un output leggibile sul piccolo schermo.
===== Personalizzazione terminale =====
==== Tasto back ====
È possibile configurare l'azione eseguita dal **tasto Back Android**: l'opzione predefinita è **nascondi tastiera on-screen**, un'ulteriore pressione esegue il **lascia applicazione**.
È possibile in alternativa associarlo al tasto **ESC** che viene quindi processato dall'applicazione in esecuzione in Termux. Per avere questa configurazione si deve modificare il file **$HOME/.termux/termux.properties** (se non esiste bisogna crearlo):
###############
# Back key
###############
### Send the Escape key.
back-key=escape
### Hide keyboard or leave app (default).
# back-key=back
Altre impostazioni configurabili nel file sono documentate in **[[https://wiki.termux.com/wiki/Terminal_Settings|Terminal Settings]]**.
==== Touch Keyboard ====
È possibile aggiungere dei tasti touch al bordo dello schermo, che si aggiungono alle possibilità offerte dalla tastiera on-screen. L'impostazione predefinita mostra i seguenti tasti:
extra-keys = [[ESC, TAB, CTRL, ALT, {key: '-', popup: '|'}, DOWN, UP]]
La personalizzazione va fatta nel file **$HOME/.termux/termux.properties**. In questo esempio si aggiunge un tasto per nascondere/visualizzare la soft-keyboard e si toglie il tasto **%%minus%%**/**%%pipe%%**.
extra-keys = [[KEYBOARD, ESC, TAB, CTRL, ALT, DOWN, UP]]
I tasti che è possibile attivare sono elencati nella pagina **[[https://wiki.termux.com/wiki/Touch_Keyboard|Touch Keyboard]]**.
Dopo aver modificato il **termux.properties** si deve eseguire **termux-reload-settings**.
==== Full screen ====
È possibile attivare la modalità **full immersive** per cui viene nascosta la barra superiore Android e gli eventuali tasti software inferiori (back, menu, indietro). È necessario eseguire nel terminale il seguente comando con i permessi dell'**utente adb shell** oppure dentro la sessione Termux sono necessari i permessi di **su**:
settings put global policy_control immersive.full=com.termux
Le impostazioni diventano **immediatamente effettive**.
Per impostare la modalità immersive per più di una app, queste vanno specificate separate da virgole:
settings put global policy_control immersive.full=com.package.one,com.package.two
Per vedere quali app hanno la modalità immersive:
settings get global policy_control
Per rimuovere l'impostazione si esegue:
settings delete global policy_control
==== Tastiera fisica ====
Se si usa una tastiera esterna (es. Bluetooth) si possano utilizzare alcune scorciatoie elencate nella pagina **[[https://wiki.termux.com/wiki/Hardware_Keyboard|Hardware Keyboard]]**:
^ Ctrl-Alt-C | Create new session |
^ Ctrl-Alt-R | Rename session |
^ Ctrl-Alt-[1-9] | Switch to session number |
^ %%Ctrl-Alt-[DOWN|UP]%% | Next/Previous session, use also **N** and **P** keys |
^ %%Ctrl-Alt-[+|-]%% | Increase/decrease text size |
^ Ctrl-Alt-RIGHT | Open drawer |
^ Ctrl-Alt-LEFT | Close drawer |
^ Ctrl-Alt-M | Show menu |
^ Ctrl-Alt-U | Select URL |
^ Ctrl-Alt-V | Paste |
===== Accesso alla SD Card =====
L'installazione predefinita non concede automaticamente a Termux il permesso di accedere allo storage Android (SD Card). Modificare da //Settings// => //Apps// => //Termux// => //Permissions//. In questo modo sarà possibile nella shell Termux accedere al contenuto di **/sdcard/** ecc.
Per comodità in una shell Termux si può eseguire il comando **[[https://wiki.termux.com/wiki/Termux-setup-storage|termux-setup-storage]]** che provvede a richiedere il permesso di accesso ai file multimediali e a creare i seguenti link simbolici:
* $HOME/storage/dcim -> /storage/emulated/0/DCIM/
* $HOME/storage/downloads -> /storage/emulated/0/Download/
* $HOME/storage/movies -> /storage/emulated/0/Movies/
* $HOME/storage/music -> /storage/emulated/0/Music/
* $HOME/storage/pictures -> /storage/emulated/0/Pictures/
* $HOME/storage/shared -> /storage/emulated/0/
Se qualcosa non funziona (errore ''Permission denied''), provare a rimuovere il permesso **File e contenuti multimediali** e assegnarlo nuovamente (problema conosciuto con Android 11).
===== Esecuzione script: "Permission denied" =====
**ATTENZIONE**: Almeno in alcune versioni di Android 6.0 c'è un **problema di permessi** che va oltre i canonici permessi **rwx** Unix, si tratta del **security context** di **Selinux**. Se un file viene creato ad esempio dalla **adb shell** dall'utente root e poi viene opportunamente attribuito all'utente Termux con i permessi opportuni, può comunque **restare inaccessibile** all'interno dell'app Termux. Ecco un esempio da una sessione terminale Termux:
id
uid=10099(u0_a99) gid=10099(u0_a99) groups=3003(inet),9997(everybody),50099(all_a99)
cd .shortcuts
ls -la
-rwxr-xr-x u0_a99 u0_a99 48 2018-07-05 09:51 01_prova
cat 01_prova
cat: can't open '01_prova': Permission denied
Con il comando **ls -Z** si vede che i file hanno un **security context** diverso; il file //pippo1// è accessibile dall'utente Termux, mentre il file //pippo2// non lo è:
-rwxr-xr-x u0_a99 u0_a99 u:object_r:app_data_file:s0:c512,c768 pippo1
-rwxr-xr-x u0_a99 u0_a99 u:object_r:app_data_file:s0 pippo2
Per **cambiare** il //security context// del file è sufficiente usare i comando:
chcon "u:object_r:app_data_file:s0:c512,c768" pippo2
===== Termux:Widget e script .shortcuts =====
Vedere il wiki **[[https://wiki.termux.com/wiki/Termux:Widget|Termux:Widget]]**.
Ecco un esempio di script da eseguire tramite Termux Widget. È sufficiente crearlo nella directory **/data/data/com.termux/files/home/.shortcuts/**:
#!/data/data/com.termux/files/usr/bin/sh
exec /data/data/com.termux/files/usr/local/bin/rsync-documents
===== Problema ambiente Termux via ADB shell =====
FIXME Questa ricetta non è funzionante al 100%. In effetti i problemi sono due: accedere con **adb shell** come **utente root** ed avere l'ambiente Termux, oppure accedere sempre con adb shell, ma come **utente termux**, sempre avendo l'ambiente Termux funzionante. Vedere l'alternativa usando **[[#ssh_con_adb_port_forward|ssh con ADB port forward]]**.
Se da un PC si accede al device via //USB Debug// e **ADB shell** non è semplice avere l'ambiente Termux funzionante; è infatti impossibile eseguire i pacchetti installati tramite **pkg install** dalla app Termux. Il problema è nelle impostazioni delle variabili d'ambiente **PATH**, **LD_LIBRARY_PATH**, ecc.
**Con i permessi di root** nella ADB shell è possibile ricreare l'ambiente opportuno. Come prima cosa si cambia utente da root a quello Termux (verificare il nome che viene determinato al momento dell'installazione di Termux, basta guardare il proprietario della directory ''/data/data/com.termux/files/'') e quindi impostare le opportune PATH:
su u0_a99
export LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib
export PATH=/data/data/com.termux/files/usr/bin:/data/data/com.termux/files/usr/bin/applets
export HOME=/data/data/com.termux/files/home
export TMPDIR=/data/data/com.termux/files/usr/tmp
export TERM=linux
* FIXME Sarà possibile eseguire i programmi installati in Termux, ma non si avrà i **permessi per accedere alla rete**, ecc.
* FIXME Sarebbe preferibile impostare **TERM=xterm-256color** che dovrebbe essere l'impostazione predefinita di Debian e di Android e che dovrebbe garantire il funzionamento della maggior parte dei tasti funzione e tasti speciali (Home, End, ecc.). Purtroppo si è riscontrato un **problema con Konsole**, che pare non supporti la sequenza di controllo **REP - Repeat ESC[Pnb**, per cui alcuni programmi a tutto schermo risultano corrotti nell'output (ad esempio il Midnight Commander).
Se si mantiene l'utente root e si esegue solo l'impostazione delle variabili di ambiente, è possibile utilizzare l'**ambiente Termux**, con i **permessi di root**, via **ADB shell**, senza restrizioni (funziona anche l'accesso alla rete). A seconda delle circostanze si dovrà **decidere** se è preferibile l'**ambiente root ADB shell** predefinito oppure quello **Termux**, soprattutto per quanto riguarda la variabile **PATH**. In alcune circostanze è infatti è necessario utilizzare i tool contenuti in **/system/bin/**, **/system/sbin/**, ecc.
Eventuali script di shell dovranno utilizzare l'opportuna riga [[wpit>Shabang]], alcune possibili scelte sono:
* **/system/bin/sh** shell predefinita della ADB shell;
* **/data/data/com.termux/files/usr/bin/sh** shell predefinita dell'ambiente Termux, di solito linkata a **dash**;
* **/data/data/com.termux/files/usr/bin/bash** shell Bash, disponibile nell'ambiente Termux;
===== SSH con ADB port forward =====
Nell'ambiente Termux si installa openssh:
apt install openssh
quindi si esegue il demone **sshd**. Per comodità si può inserire il comando in uno script creato nella cartella **.shortcuts/**, in questo modo sarà possibile avviare il demone ssh con un tap sul Termux Widget. Ecco un esempio:
#!/data/data/com.termux/files/usr/bin/sh
echo "To connect from the ADB host:"
echo
echo "adb forward tcp:8022 tcp:8022"
echo "ssh localhost -p 8022"
termux-wake-lock
sshd
echo
echo "Wakelock requested, will run in background."
sleep 5
**ATTENZIONE**:
* Si è eseguito **termux-wake-lock** prima di lanciare **sshd**. In questo modo si ha la garanzia che il processo non venga sospeso o rallentato dal sistema operativo Android. Questo richiede il permesso (tramite pop-up) di disattivare l'**ottimizzazione batteria**. Per revocare il permesso si va su //Settings// => //Battery// => //Three dots menu// => //Battery optimization//.
* Il demone eseguito nel terminale **non sopravvive alla chiusura del terminale** stesso.
* Il demone **non sopravvive al reboot** del telefono.
* FIXME: Quanta batteria consuma?
Poiché non è possibile usare l'autenticazione password, si deve autorizzare l'utente remoto con una **/data/data/com.termux/files/home/.ssh/authorized_keys**. Verificare i permessi e il //SELinux security context// sul file authorized_keys:
ls -lZ
total 16
-rw------- 1 u0_a96 u0_a96 u:object_r:app_data_file:s0:c512,c768 394 2019-09-17 11:08 authorized_keys
-rw------- 1 u0_a96 u0_a96 u:object_r:app_data_file:s0:c512,c768 1823 2018-11-07 17:41 id_rsa
-rw------- 1 u0_a96 u0_a96 u:object_r:app_data_file:s0:c512,c768 398 2018-11-07 17:41 id_rsa.pub
-rw-r--r-- 1 u0_a96 u0_a96 u:object_r:app_data_file:s0:c512,c768 1997 2019-08-10 07:51 known_hosts
Sul PC GNU/Linux avviare il port forward via ADB e poi collegarsi con ssh:
adb forward tcp:8022 tcp:8022
ssh localhost -p 8022
===== Termux:API =====
Per utilizzare le API Android da Termux è necessario installare l'app **Termux:API** e concedere ad essa tutti i permessi richiesti. Nel terminale è necessario installare una tantum il pacchetto **termux-api**
pkg install termux-api
quindi si deve avviare l'intent della app di nome **cmp=com.termux.api/.KeepAliveService**, questo è opportuno farlo ogni volta che si vuole accedere ad una API, poiché il sistema operativo potrebbe aver fermato il servizio:
termux-api-start
==== termux-location ====
usage: termux-location [-p provider] [-r request]
Get the device location.
-p provider location provider [gps/network/passive] (default: gps)
-r request kind of request to make [once/last/updates] (default: once)
Vedere **[[https://developerlife.com/2010/10/20/gps/|Android Location Providers]]**, **[[https://developers.google.com/location-context/fused-location-provider/|Fused Location Provider API]]** e **[[https://developer.android.com/reference/android/location/Location|Android Location Class]]**.
* **gps** Usa la posizione fornita dai satelliti, può necessitare di diverso tempo prima di una risposta. Richiede il permesso ACCESS_FINE_LOCATION.
* **network** Determina la posizione con le celle telefoniche e gli access point WiFi, tramite una richiesta ai servizi Google. Richiede il permesso ACCESS_COARSE_LOCATION oppure ACCESS_FINE_LOCATION.
* **passive** Determina la posizione senza iniziare una procedura di fix, ma sfruttanto altre applicazioni che l'hanno determinata a loro volta. Sebbene richieda il permesso ACCESS_FINE_LOCATION, potrebbe restituire una posizione //coarse// se il GPS non è attivo.
* **once** Richiede la posizione al provider specificato. In caso di mancanza di segnale la risposta è vuota.
* **last** Restituisce l'ultima posizione conosciuta del dispositivo, in effetti non attiva la lettura del GPS né dei segnali radio (celle telefoniche o WiFi), né richieste network.
* **updates** Il //Fused Location Provider API// prevede di poter ricevere gli aggiornamenti della posizione, tramite una callback. FIXME Come è implementato questo metodo in Termux:API?
Quindi la richiesta di posizione meno dispendiosa in termini di batteria è quella che combina **passive** e **last**. Attenzione che in questo caso il dato potrebbe essere vecchio, e ciò è evidenziato dal campo **elapsedMs** (millisecondi):
termux-location -p passive -r last
{
"latitude": 43.8922787,
"longitude": 11.10043158,
"altitude": 134.0,
"accuracy": 49.3120002746582,
"bearing": 0.0,
"speed": 0.0,
"elapsedMs": 796120,
"provider": "gps"
}
==== termux-job-scheduler ====
Il comando consente di schedulare tramite il **JobScheduler di Android** l'esecuzione di un comando. Il funzionamento si basa sulla **[[https://developer.android.com/reference/kotlin/android/app/job/JobScheduler|JobScheduler class]]** introdotta con **Android 5.0 Lollipop** (API 21). Con **Android 7.0 Nougat** (API 24) è stato imposto un limite minimo all'intervallo di esecuzione, per cui il **periodo più breve impostabile è di 15 minuti (900000 ms)**.
FIXME: Quando si imposta un JobScheduler, lo script viene eseguito immediatamente una prima volta? O la prima volta viene eseguito alla scadenza del periodo? Si è sperimentato che a volte accade il primo caso, a volte il secondo.
FIXME: Nella documentazione della JobScheduler class (vedi sopra) si legge //While a job is running, the system holds a wakelock on behalf of your app//. È vero anche per i job eseguiti dal termux-job-scheduler? Dalla notifica che appare durante l'esecuzione pare di no, perché compare l'opzione //Acquire wakelock//.
termux-job-scheduler --script /data/data/com.termux/files/home/bin/script --period-ms 901000
termux-job-scheduler --pending
Pending Job 0: /data/data/com.termux/files/home/bin/script (periodic: 901000ms) (battery not low)
Sembra che **non sia possibile specificare parametri** aggiuntivi da passare allo script.
È possibile impostare alcuni flag per limitare l'esecuzione in base a vari parametri: **network**, **battery-not-low**, **charging**, etc. Vedere in proposito **%%termux-job-scheduler --help%%**.
La schedulazione Android **non è precisa** al secondo, ad esempio avendo impostato un periodo di 15 minuti, l'effettivo periodo misurato è andato da un **minimo di 14:59** ad un **massimo di 22:55**.
Quando lo scheduler Android avvia un job, nella barra delle notifiche compare l'icona di Termux. Espandendo i pannello viene mostrato quanto segue:
{{termux-jos-scheduler-notification.png?nolink&280|}}
Per poter **cancellare un job in base al suo ID** è necessario avere almeno **Android 7.0 Nougat**, altrimenti è necessario cancellare tutti i job.
==== termux-telephony-cellinfo ====
Mostra informazioni sulla cella telefonica su cui si è registrato il telefono e quelle in prossimità:
{
"type": "lte",
"registered": true,
"asu": 30,
"dbm": -110,
"level": 2,
"ci": 256427581,
"pci": 154,
"tac": 57734,
"mcc": 222,
"mnc": 50
},
{
"type": "lte",
"registered": false,
"asu": 24,
"dbm": -116,
"level": 1,
"pci": 358
},
Questo il significato di alcuni dei campi:
^ cid | GSM Cell ID, e.g. ??? |
^ lac | GSM Location Area Code e.g. ??? |
^ ci | LTE Cell ID, e.g. 256427581 |
^ tac | LTE Tracking Area Code LTE e.g. 57734 |
^ pci | Physical Cell Id. e.g. 154 |
^ mcc | Mobile Country Code e.g. 222 |
^ mnc |Mobile Network Code e.g. 50 |