O que é o BusyBox?
(specular.fi)- BusyBox é um binário multicall que fornece vários comandos em um único executável; até o
wgetpadrão do Alpine é executado via BusyBox - No contêiner Alpine,
/usr/bin/wgetnão era um binário real, mas um link simbólico apontando para/bin/busybox - Ao ser executado, o BusyBox lê o nome de chamada em
argv[0]e determina qual applet executar a partir do último nome do caminho - Cada applet é localizado pelo nome e entra na respectiva função
main; owgeté implementado emwget.ce, no fim, executawget_main - É possível ver os comandos compilados com
busybox --list; no exemplo do Alpine, aparecem 304 e cada utilitário parece uma versão reduzida
Como o BusyBox funciona
- O BusyBox usa uma estrutura de binário multicall (multicall binary), oferecendo vários comandos em um único executável
- Em um contêiner Alpine,
/usr/bin/wgetnão era um arquivo executável real, e sim um link simbólico apontando para/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 - Em
/usr/bin, mais de 130 executáveis parecem vir de um único binário, o que está ligado à estrutura de binário multicall do BusyBox - Ao iniciar, o BusyBox obtém o nome invocado a partir de
argv[0]e extrai apenas o último nome do caminho para decidir qual applet executarapplet_name = argv[0]; if (applet_name[0] == '-') applet_name++; applet_name = bb_basename(applet_name); - Também funciona ao passar explicitamente o nome do applet, como em
busybox ls -1; se for informado um nome inexistente, será exibidoapplet not found/ # busybox ls -1 bin dev etc home / # busybox meheh meheh: applet not found
Estrutura dos applets e forma de instalação
- O BusyBox procura o applet pelo nome e então executa a função
maincorrespondenteint 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 tem seu próprio arquivo C; o
wgeté implementado emwget.c - As configurações de cada applet são definidas em forma de comentários no código; a configuração de
WGETincluiwget (41 kb), ativação padrão, ajuda descrevendo-o como um utilitário para baixar arquivos de servidores HTTP e FTP de forma não interativa, além do alvo 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 - No fim, o applet
wgetentra emwget_mainint wget_main(int argc UNUSED_PARAM, char **argv) - O BusyBox também oferece suporte a hard links, e em
busybox --install -so-sindica a criação de links simbólicosbusybox --install -s - A lista de comandos incluídos na compilação pode ser vista com
busybox --list; no ambiente de exemplo do Alpine, aparecem 304/ # busybox --list | wc -l 304 - Muitos comandos do Alpine funcionam como uma interface para o binário baseado em BusyBox, e cada utilitário parece uma versão reduzida em comparação com o utilitário original completo
1 comentários
Opiniões no Lobste.rs
A resposta à pergunta citada está mais para uma reimplementação
A apresentação do BusyBox está em https://busybox.net/about.html, e o código-fonte está em https://github.com/vda-linux/busybox_mirror
É bem irritante quando um programa finge ter um nome diferente do que realmente é
O pior caso é quando você executa
gccno macOS e na verdade recebe clang; o PowerShell também funciona de forma parecida. Seria melhor simplesmente usar outro nomeO Nixpkgs precisa aplicar muitos patches como https://github.com/NixOS/nixpkgs/…, e nem projetos famosos como o sqlite são exceção. Já o macOS basicamente escolheu o caminho de enganar pelo caminho
ccDeve haver muitos makefiles com
gcchardcoded, e o mesmo acontece em outros contextos. Por exemplo, como muitos programas existentes verificamxterm-*na variável de ambienteTERMem vez de usar o banco de dadosterminfo, que seria a solução correta, escolher outro nome não funcionaAo diagnosticar problemas estranhos em contêineres, eu uso bastante
podman cp /usr/bin/busybox-static somecontainer:/binO toybox também tem uma estrutura parecida
Algumas ferramentas parecem ter sido trazidas ou portadas de outros lugares, mas muitas foram implementadas do zero para o BusyBox, com o objetivo de serem pequenas e usarem apenas funcionalidades limitadas de libc para também compilarem pequenas com linkagem estática. Outra vantagem é poder usar essas ferramentas em scripts de shell como se fossem comandos embutidos. Algumas rodam com fork+jump em vez de fork+exec, e algumas até rodam sem fork, por chamada de função comum
Complementando, segundo Toybox on Wikipedia, “Toybox was started at the beginning of 2006 after Rob Landley quit as BusyBox maintainer in a dispute with BusyBox's original creator Bruce Perens”
Na prática, é uma reimplementação. Ainda assim, se a licença permitir, não seria surpreendente se algum código tivesse sido aproveitado da implementação original maior
Segundo a Wikipédia:, o BusyBox foi escrito originalmente por Bruce Perens em 1995, e em 1996 foi declarado completo para o uso pretendido. O objetivo inicial era colocar em um único disquete um sistema totalmente inicializável que servisse como disco de recuperação e instalador da distribuição Debian. Depois disso, ele se expandiu e virou de fato o conjunto padrão de ferramentas essenciais de espaço de usuário em dispositivos Linux embarcados e instaladores de distribuições Linux; como cada executável Linux exige alguns KB de overhead, juntar mais de 200 programas em um só pode economizar bastante espaço em disco e memória
Nesse contexto, o Toybox também tem estrutura e filosofia parecidas, mas com licença BSD. Pelo que lembro, o principal desenvolvedor, Rob Landley, via uma licença mais fácil de aceitar comercialmente como uma forma de o projeto poder ser incluído em dispositivos Android e, com isso, dar a todos os celulares e tablets Android o potencial de virar um ambiente de desenvolvimento parecido com Unix. O Toybox ainda parece fazer parte do Android, mas sem ferramentas de camada superior como o Termux, o Android não é tão fácil de usar como Unix
Ainda mais considerando que o Google passou anos ameaçando bloquear o Termux
Também existe um port para Windows: https://github.com/rmyorston/busybox-w32
O tamanho pequeno do BusyBox torna esse tipo de port mais viável. Mas hoje isso parece um pouco menos relevante, já que agora dá para simplesmente rodar Linux dentro do Windows