Primo, perché ci sono /lib
separati e /lib64
:
Le menzioni standard della gerarchia del filesystem che separano /lib
e /lib64
esistono perché:
10.1. Ci possono essere una o più varianti della directory /lib su sistemi che supportano più di un formato binario che richiede librerie separate. (...) Questo è comunemente usato per il supporto a 64 o 32 bit su sistemi che supportano più formati binari, ma richiedono librerie con lo stesso nome. In questo caso, /lib32 e /lib64 potrebbero essere le directory della libreria e /lib un collegamento simbolico a una di esse.
Sulla mia Slackware 14.2 ad esempio ci sono /lib
e /lib64
rispettivamente per le librerie a 32 e 64 bit anche se/lib
non è un collegamento simbolico come suggerirebbe lo snippet FHS:
$ ls -l /lib/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11 2016 /lib/libc.so.6 -> libc-2.23.so
$ ls -l /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11 2016 /lib64/libc.so.6 -> libc-2.23.so
Ci sono due libc.so.6
librerie in /lib
e /lib64
.
Ogni binario ELF costruito dinamicamente contiene un percorso codificato per l'interprete, in questo caso /lib/ld-linux.so.2
o /lib64/ld-linux-x86-64.so.2
:
$ file main
main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not stripped
$ readelf -a main | grep 'Requesting program interpreter'
[Requesting program interpreter: /lib/ld-linux.so.2]
$ file ./main64
./main64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped
$ readelf -a main64 | grep 'Requesting program interpreter'
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
Il compito dell'interprete è caricare le librerie condivise necessarie. Puoi chiedere a un interprete GNU quali librerie caricherebbe senza nemmeno eseguire un binario usando LD_TRACE_LOADED_OBJECTS=1
o un ldd
involucro:
$ LD_TRACE_LOADED_OBJECTS=1 ./main
linux-gate.so.1 (0xf77a9000)
libc.so.6 => /lib/libc.so.6 (0xf760e000)
/lib/ld-linux.so.2 (0xf77aa000)
$ LD_TRACE_LOADED_OBJECTS=1 ./main64
linux-vdso.so.1 (0x00007ffd535b3000)
libc.so.6 => /lib64/libc.so.6 (0x00007f56830b3000)
/lib64/ld-linux-x86-64.so.2 (0x00007f568347c000)
Come puoi vedere, un determinato interprete sa esattamente dove cercare le librerie:la versione a 32 bit cerca le librerie in /lib
e la versione a 64 bit cerca le librerie in /lib64
.
Lo standard FHS dice quanto segue su /bin
:
/bin contiene comandi che possono essere utilizzati sia dall'amministratore di sistema che dagli utenti, ma che sono richiesti quando non sono montati altri filesystem (ad es. in modalità utente singolo). Può anche contenere comandi che sono usati indirettamente dagli script.
IMO il motivo per cui non ci sono /bin
separati e /bin64
è che se avessimo il file con lo stesso nome in entrambe queste directory non potremmo chiamarne una direttamente perché dovremmo inserire /bin
o /bin64
prima in$PATH
.
Tuttavia, nota che quanto sopra è solo una convenzione:al Linuxkernel non interessa davvero se hai /bin
separato e /bin64
.Se li vuoi, puoi crearli e configurare il tuo sistema di conseguenza.
Hai anche menzionato Android - nota che, ad eccezione dell'esecuzione di un kernel Linux modificato, non ha nulla a che fare con i sistemi GNU come Ubuntu - niente glibc, niente bash (per impostazione predefinita, puoi ovviamente compilarlo e distribuirlo manualmente), e anche la struttura delle directory è completamente diversa .
Il motivo è che le directory lib/lib64 possono contenere file che hanno lo stesso nome perché quelle sono librerie condivise con diversi programmi. Metterli in directory separate risolve il conflitto. Non c'è (di solito...) nessuna buona ragione per distribuire eseguibili con lo stesso nome sullo stesso sistema che sono a 32/64 bit, ma poiché può esserci una combinazione di eseguibili, le librerie condivise devono essere fornite.