Gestire link con update-alternatives
![]()
Le shell *nix sono delle miniere di chicche utili per l'amministratore di sistema.
Fra queste, ce n'è una che ho sempre trovato particolarmente intrigante ed è update-alternatives (o alternatives nei sistemi redhat-based).
Questo comando permette di gestire link simbolici e risulta comodo quando ci sono gruppi di oggetti (alternative) a cui deve afferire il link.
Ad es. supponiamo di avere 4 oggetti e un link che, in base alla necessità, possa puntare ad uno dei 4.
Si tratta quindi di avere:
/path/oggetto/1/path/oggetto/2/path/oggetto/3/path/oggetto/4
Se ad es. volessi un link generico che punti prima al 2, poi al 4 , poi all'1 e poi di nuovo al 2, una gestione ordinaria di detto link avverrebbe grossomodo così:
ln -s /path/oggetto/2 /path/link/oggetto
...
rm /path/link/oggetto
ln -s /path/oggetto/4 /path/link/oggetto
...
rm /path/link/oggetto
ln -s /path/oggetto/1 /path/link/oggetto
...
rm /path/link/oggetto
ln -s /path/oggetto/1 /path/link/oggetto
Creo un link, lo cancello, lo ricreo, lo cancello... e così via.
Tutto questo può essere semplificato con update-alternatives, che centralizza questo tipo di gestione dei link, creando tutti i possibili link per poi eleggere il “link leader” (il link effettivamente attivo) in base all'esigenza.
Aggiungere alternatives
Per creare il gruppo di alternative si usa --install:
# sintassi
# --install <path_link> <nome> <path_fisico> <priorità>
# la priorità è un intero, l'intero più grande diventa il link di default
sudo update-alternatives --install /path/link/oggetto "nome gruppo" /path/oggetto/1 100
sudo update-alternatives --install /path/link/oggetto "nome gruppo" /path/oggetto/2 110
sudo update-alternatives --install /path/link/oggetto "nome gruppo" /path/oggetto/3 150
sudo update-alternatives --install /path/link/oggetto "nome gruppo" /path/oggetto/4 120
Attivare un alternative (elezione del link leader)
Nell'esempio che seguirà, vogliamo che il link che punta ad oggetto_2, punti ad oggetto_1:
È possibile modificare interattivamente il link leader con --config:
# --config <nome>
sudo update-alternatives --config 'nome gruppo'
Ci sono 4 programmi che forniscono 'nome gruppo'.
Selezione Comando
-----------------------------------------------
1 /path/oggetto/1
+ 2 /path/oggetto/2
* 3 /path/oggetto/3
4 /path/oggetto/4
Invio per mantenere l'attuale selezione[+], o inserire il numero di selezione: 1
oppure da cli (la modalità scriptabile):
# --set <nome> <path_fisico>
sudo update-alternatives --set "nome gruppo" /path/oggetto/1
oppure automaticamente (scriptabile anche questa), con la selezione automatica della voce con priorità più alta:
# --auto <nome>
sudo update-alternatives --auto 'nome gruppo'
Rimuovere un link
La rimozione di un alternative dal gruppo, si fa con --remove. Rimuoviamo “oggetto_2” ad es.:
# --remove <nome> <path_fisico>
sudo update-alternatives --remove 'nome gruppo' /path/oggetto/2
Per la rimozione di tutto il gruppo invece:
# -- remove-all <nome>
sudo update-alternatives --remove-all 'nome gruppo'
Visualizzare i gruppi di link
Per elencare tutti i gruppi di link presenti (ce ne sono diversi già a sistema) si usa il flag --list:
sudo update-alternatives --list
google-chrome auto /usr/bin/google-chrome-stable
jre_25 manual /usr/lib/jvm/java-latest-openjdk
java manual /usr/lib/jvm/java-25-openjdk/bin/java
jre_openjdk auto /usr/lib/jvm/java-25-openjdk
wine-dxgi(x86-32) auto /usr/lib/wine/i386-windows/wine-dxgi.dll
javadocdir auto /usr/share/javadoc/java-24-openjdk/api
jre_26 auto /usr/lib/jvm/java-latest-openjdk
jre_25_openjdk auto /usr/lib/jvm/java-25-openjdk
javadocdir_25 auto /usr/share/javadoc/java-latest-openjdk/api
libnssckbi.so.x86_64 auto /usr/lib64/pkcs11/p11-kit-trust.so
w
...
che restituisce la lista delle alternatives.
Visualizzare le info di un gruppo di link
La visualizzazione delle info di una particolare alternative può avvenire con --config (che è più una modalità di configurazione come sappiamo), o col più verboso --display.
--config mostra l'id dell'oggetto e il path fisico:
sudo update-alternatives --config 'nome gruppo'
Ci sono 4 programmi che forniscono 'nome gruppo'.
Selezione Comando
-----------------------------------------------
1 /path/oggetto/1
+ 2 /path/oggetto/2
* 3 /path/oggetto/3
4 /path/oggetto/4
Invio per mantenere l'attuale selezione[+], o inserire il numero di selezione:
Notare che nel display di --config, il simbolo [*] rappresenta la voce con priorità più alta, il simbolo [+] rappresenta quella attiva.
--display fornisce informazioni in più:
sudo update-alternatives --display 'nome gruppo'
'nome gruppo' - stato: manuale.
il link attualmente punta a /path/oggetto/2
/path/oggetto/1 - priorità 100
/path/oggetto/2 - priorità 110
/path/oggetto/3 - priorità 150
/path/oggetto/4 - priorità 120
La migliore versione attuale è /path/oggetto/3.
Restituisce info sullo stato del link leader, manuale (se il leader è stato scelto con --config o --set) o automatico (se il leader è stato scelto con --auto), elenca i path fisici, le loro priorità e i follower che vedremo subito dopo.
Link correlati
Un altro flag interessante è l'ex --slave mutato nel più politicamente corretto --follower che dà la possibilità di aggiungere molteplici triple, <nome gruppo, link, path> tutte associate al link leader.
Se il contesto afferito dal link leader prevede che vi siano altri contesti associati che devono variare di conseguenza, piuttosto che gestire n contesti separatamente, ne gestisco sempre uno che trascinerà tutti i contesti associati con --follower
I follower possono essere aggiunti in blocco durante la creazione delle alternatives:
# --follower <path_link_follower> <nome_follower> <path_fisico_follower>
sudo update-alternatives \
--install /usr/bin/mytool mytool /usr/bin/mytool-1.0 10 \
--follower /usr/share/man/man1/mytool.gz mytool.gz /usr/share/man/man1/mytool-1.0.1.gz
O aggiunti in un secondo momento:
# --add-follower <nome> <path_link> <path_link_follower> <nome_follower> <path_fisico_follower>
sudo update-alternatives \
--add-follower mytool /usr/bin/mytool-1.0 /usr/share/applications/mytool.desktop mytool.desktop /usr/share/applications/mytool-1.0.1.desktop
Così come i follower possono essere aggiunti singolarmente, allo stesso modo possono anche essere rimossi:
# --remove-follower <nome> <path_fisico> <nome_follower>
sudo update-alternatives \
--remove-follower mytool /usr/share/applications/mytool-1.0.1.desktop mytool.desktop
Aggiungiamo una seconda alternative all'esempio iniziale per avere un link leader che punti al binario e due follower che puntino ai rispettivi man e lanciatore:
sudo update-alternatives \
--install /usr/bin/mytool mytool /usr/bin/mytool-2.0 20 \
--follower /usr/share/man/man1/mytool.gz mytool.gz /usr/share/man/man1/mytool-2.0.1path follower_name.gz \
--follower /usr/share/applications/mytool.desktop mytool.desktop /usr/share/applications/mytool-2.0.1.desktop
possiamo notare come sia semplice cambiare parecchi link con un colpo solo a differenza di una gestione manuale
sudo update-alternatives --config mytool
Ci sono 2 programmi che forniscono 'mytool'.
Selezione Comando
-----------------------------------------------
1 /usr/bin/mytool-1.0
*+ 2 /usr/bin/mytool-2.0
Invio per mantenere l'attuale selezione[+], o inserire il numero di selezione:
La selezione, in un colpo solo, trascinerà con sè il link all'eseguibile, al man e al lanciatore .desktop.
--display mostra per bene quanto sia articolata la sua configurazione:
sudo update-alternatives --display mytool
mytool - stato: manuale.
il link attualmente punta a /usr/bin/mytool-2.0
/usr/bin/mytool-1.0 - priorità 10
seguace mytool.desktop: /usr/share/applications/mytool-1.0.1.desktop
seguace mytool.gz: /usr/share/man/man1/mytool-1.0.1.gz
/usr/bin/mytool-2.0 - priorità 20
seguace mytool.desktop: /usr/share/applications/mytool-2.0.1.desktop
seguace mytool.gz: /usr/share/man/man1/mytool-2.0.1.gz
La migliore versione attuale è /usr/bin/mytool-2.0.
Per usare update-alternatives anche senza avere privilegi di amministrazione, si può ricorrere ai flag --altdir e --admindir che servono per specificare le cartelle (su cui chiaramente si devono avere permessi r/w) in cui vengono depositati, rispettivamente, i puntamenti ai path fisici e le configurazioni mostrate da --display
mkdir -p $HOME/.local/var/lib/alternatives
mkdir -p $HOME/.local/etc/alternatives
# bonus: definizione di un alias in .bash_aliases per esempio
alias update-local-alternatives='/usr/bin/update-alternatives --altdir "$HOME/.local/etc/alternatives" --admindir "$HOME/.local/var/lib/alternatives"'
In questo modo è possibile usare update-alternatives con l'alias nella propria home, senza privilegi di amministrazione, sacrificando un pizzico di bash-completion.