¿Qué es BusyBox?
(specular.fi)- BusyBox usa una estructura de binario multicall que ofrece varios comandos en un solo ejecutable, y el
wgetpredeterminado de Alpine también se ejecuta a través de BusyBox - En un contenedor Alpine,
/usr/bin/wgetno era un binario real sino un enlace simbólico que apuntaba a/bin/busybox - Al ejecutarse, BusyBox lee el nombre invocado desde
argv[0]y determina qué applet ejecutar usando el último nombre de la ruta - Cada applet se busca por nombre y entra a su función
maincorrespondiente;wgetestá implementado enwget.cy finalmente se ejecutawget_main - Se pueden ver los comandos compilados con
busybox --list, y en el ejemplo de Alpine aparecen 304, mientras que cada utilidad parece una versión reducida
Cómo funciona BusyBox
- BusyBox usa una estructura de binario multicall (multicall binary) que ofrece varios comandos en un solo ejecutable
- En un contenedor Alpine,
/usr/bin/wgetno era un ejecutable real sino un enlace simbólico que apuntaba a/bin/busyboxdocker run --rm -it alpine sh / # which wget /usr/bin/wget / # ls -lah /usr/bin/wget lrwxrwxrwx 1 root root 12 Apr 15 04:51 /usr/bin/wget -> /bin/busybox - En
/usr/bin, más de 130 ejecutables parecen provenir de un solo binario, lo que se relaciona con la estructura de binario multicall de BusyBox - Al ejecutarse, BusyBox toma el nombre invocado desde
argv[0], extrae solo el último nombre de la ruta y decide qué applet ejecutarapplet_name = argv[0]; if (applet_name[0] == '-') applet_name++; applet_name = bb_basename(applet_name); - También funciona si se pasa explícitamente el nombre del applet, como en
busybox ls -1; si se le da un nombre inexistente, muestraapplet not found/ # busybox ls -1 bin dev etc home / # busybox meheh meheh: applet not found
Configuración de applets y forma de instalación
- BusyBox busca el applet por nombre y luego ejecuta la función
maincorrespondiente de ese appletint applet = find_applet_by_name(name); // ... run_applet_no_and_exit(applet, name, argv); // ... xfunc_error_retval = applet_main[applet_no](argc, argv); - Cada applet tiene su propio archivo C, y
wgetestá implementado enwget.c - La configuración de cada applet está definida en forma de comentarios dentro del código; la configuración de
WGETincluyewget (41 kb), activación predeterminada, una ayuda que lo describe como una utilidad para descargar archivos de servidores HTTP y FTP sin interacción, y el objetivo de buildwget.o//config:config WGET //config: bool "wget (41 kb)" //config: default y //config: help //config: wget is a utility for non-interactive download of files from HTTP //config: and FTP servers. //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) //kbuild:lib-$(CONFIG_WGET) += wget.o - Al final, el applet
wgetentra enwget_mainint wget_main(int argc UNUSED_PARAM, char **argv) - BusyBox también soporta enlaces duros, y en
busybox --install -s,-ssignifica crear enlaces simbólicosbusybox --install -s - La lista de comandos incluidos en la compilación puede verse con
busybox --list, y en el entorno de ejemplo de Alpine aparecen 304/ # busybox --list | wc -l 304 - Varios comandos de Alpine funcionan como una interfaz hacia binarios basados en BusyBox, y cada utilidad parece una versión reducida frente a la utilidad original completa
1 comentarios
Opiniones en Lobste.rs
La respuesta a la pregunta citada está más cerca de una reimplementación
La introducción a BusyBox está en https://busybox.net/about.html y el código fuente está en https://github.com/vda-linux/busybox_mirror
Es bastante molesto que un programa finja tener un nombre distinto del real
El peor caso es cuando ejecutas
gccen macOS y en realidad obtienes clang; PowerShell también funciona de forma parecida. Sería mejor que simplemente usaran otro nombreNixpkgs tiene que aplicar muchos parches como https://github.com/NixOS/nixpkgs/…, y ni siquiera proyectos conocidos como sqlite son la excepción. En cambio, macOS simplemente optó por la ruta engañosa
ccDebe haber muchos makefiles con
gcchardcodeado, y pasa algo parecido en otros contextos. Por ejemplo, como muchos programas existentes revisanxterm-*en la variable de entornoTERMen lugar de usar la base de datosterminfo, que sería la solución correcta, elegir otro nombre no funcionaCuando diagnostico problemas raros en contenedores, uso seguido
podman cp /usr/bin/busybox-static somecontainer:/bintoybox tiene una estructura parecida
Algunas herramientas parecen traídas o portadas desde otros lugares, pero muchas fueron implementadas de nuevo para BusyBox, y el objetivo es mantenerlas pequeñas y usar solo funciones limitadas de libc para que al compilar con enlace estático sigan siendo pequeñas. Otra ventaja es que en scripts de shell estas herramientas pueden usarse como si fueran comandos integrados. Algunas se ejecutan con fork+jump en vez de fork+exec, y unas cuantas incluso pueden ejecutarse sin fork, como una llamada normal a función
Como agregado, según Toybox en Wikipedia, “Toybox fue iniciado a comienzos de 2006 por Rob Landley después de dejar su rol como mantenedor de BusyBox tras una disputa con Bruce Perens, el creador original de BusyBox”
En realidad sí es una reimplementación. Aun así, si la licencia lo permite, no sería sorprendente que hubiera tomado algo de código de la implementación original más grande
Según la 'pedia:, BusyBox fue escrito originalmente por Bruce Perens en 1995, y en 1996 se declaró terminado para su uso previsto. El objetivo inicial era meter en un solo disquete un sistema completo y arrancable que sirviera como disco de rescate e instalador para la distribución Debian. Después se expandió hasta convertirse en el conjunto de herramientas básicas de espacio de usuario de facto estándar para dispositivos Linux embebidos y para instaladores de distribuciones Linux, y como cada ejecutable de Linux requiere varios KB de sobrecarga, combinar más de 200 programas en uno solo puede ahorrar bastante espacio en disco y memoria
Relacionado con esto, Toybox también tiene una estructura y filosofía parecidas, pero con licencia BSD. Si mal no recuerdo, su desarrollador principal, Rob Landley, pensaba que una licencia más fácil de aceptar comercialmente permitiría incluirlo en dispositivos Android, y que eso podría convertir a todos los teléfonos y tablets Android en una especie de entorno de desarrollo similar a Unix. Toybox todavía parece ser parte de Android, pero sin herramientas de apoyo en capas superiores, como Termux, Android no es tan fácil de usar como Unix
Más aún considerando que Google lleva años amenazando con bloquear Termux
También hay un port para Windows: https://github.com/rmyorston/busybox-w32
El tamaño reducido de BusyBox hace que este tipo de port sea más viable. Aunque ahora que puedes simplemente ejecutar Linux dentro de Windows, parece haber perdido algo de relevancia